同一列上具有多个聚合的 T-SQL Pivot
Posted
技术标签:
【中文标题】同一列上具有多个聚合的 T-SQL Pivot【英文标题】:T-SQL Pivot with multiple aggregates on the same column 【发布时间】:2013-08-11 20:04:36 【问题描述】:这似乎应该是一个常见的需求,但我没有看到如何使用 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 语句逻辑吗?
谢谢!
【问题讨论】:
SQL Server PIVOT - Multiple Aggregates 的可能重复项 【参考方案1】:是的。
只需使用旧样式的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 在 PIVOT
中,但 TSQL 没有。
【讨论】:
【参考方案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
【讨论】:
【参考方案3】:您必须制作两个 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
看看this fiddle example
【讨论】:
这比只使用CASE
效率要低得多,因为您执行了两次分组和聚合(以及添加额外的联接)
无论如何都是一种选择。以上是关于同一列上具有多个聚合的 T-SQL Pivot的主要内容,如果未能解决你的问题,请参考以下文章