5

这似乎应该是一个常见的需求,但我没有看到如何使用 T-SQL PIVOT 函数来做到这一点。具体来说,我想通过 Pivot 列值计算列的 AVG 和 STDEV。数据看起来像这样(省略了很多数据,但这很重要):

--------------------------------------------------------------------------
ID           Year     PersonID     Score 
--------------------------------------------------------------------------
106          2001        1          20
107          2002        1          30       
108          2003        1          40       
109          2004        1          50     
106          2002        2          20
107          2003        2          50       
108          2004        2          30       
109          2005        2          10   
--------------------------------------------------------------------------

我想看到以下输出

--------------------------------------------------------------------------
NonPivotCol1 NonPivotCol2  2001_Mean   2001_Avg  2002_Mean  2002_Avg  Etc 
--------------------------------------------------------------------------
Some Value   Some Value       32          5.2       28          3.1 
Etc. 
--------------------------------------------------------------------------

我需要恢复到旧的 CASE 语句逻辑吗?

谢谢!

4

3 回答 3

4

是的。

只需使用旧式CASE语法。

SELECT AVG(CASE WHEN Year = 2001 THEN Score END) AS 2001_Avg,
       STDEV(CASE WHEN Year = 2001 THEN Score END) AS 2001_StDev /*...*/

PIVOT无论如何,这只是(不太通用的)语法糖。

Oracle 支持多个聚合PIVOT但 TSQL 不支持。

于 2013-08-11T20:08:09.453 回答
2

用例语句。无论如何,您必须指定所有列,我会说这种情况比枢轴更有用

select
  avg(case when [Year] = 2001 then [Score] else null end) as [2001_Avg],
  avg(case when [Year] = 2002 then [Score] else null end) as [2002_Avg]
from Table1
于 2013-08-11T20:13:05.223 回答
0

您必须制作两个 PIVOT 并加入它们

WITH MinPivot AS
(
  SELECT 
         [2001] AS [2001_MEAN], 
         [2002] AS [2002_MEAN], 
         [2003] AS [2003_MEAN], 
         [2004] AS [2004_MEAN], 
         [2005] AS [2005_MEAN]
  FROM
  (
    SELECT Year,Score
    FROM Table1
  ) As S
  PIVOT
  (
     STDEV(Score)
     FOR Year in([2001],[2002],[2003],[2004],[2005])
  )
  AS pvt
),
AvgPivot AS
(
  SELECT 
         [2001] AS [2001_AVG],
         [2002] AS [2002_AVG],
         [2003] AS [2003_AVG], 
         [2004] AS [2004_AVG], 
         [2005] AS [2005_AVG] 
  FROM
  (
    SELECT Year,Score
    FROM Table1
  ) As S
  PIVOT
  (
     AVG(Score)
     FOR Year in([2001],[2002],[2003],[2004],[2005])
  )
  AS pvt
)

SELECT *
FROM MinPivot M
CROSS JOIN AvgPivot A

看看这个小提琴示例

于 2013-08-11T20:06:55.740 回答