这似乎应该是一个常见的需求,但我没有看到如何使用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语句逻辑?
谢谢!
答案 0 :(得分: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 supports multiple aggregates,但TSQL没有。{/ p>
答案 1 :(得分:2)
用例陈述。无论如何你必须指定所有列,我会说这个案例比pivot更有用
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
答案 2 :(得分: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