在没有 PIVOT 运算符的情况下执行数据透视

Perform pivot without PIVOT operator

我在设计程序时遇到困难,该程序将在稍后给出的 table 上使用给定聚合执行数据透视。程序应该 动态地 从 Sales.Month 中获取所有条目并使用传递到程序中的聚合在其上进行枢轴 table ,例如,如果我们将传递 SUM (使用 VARCHAR 传递和然后执行动态创建的查询)在销售:

销售额:

Item   Month  Price
-------------------
Book     Jan    230
Book     Jan    100
Game     Jan     50
Game     Feb     80
Stick    Mar    190

总计:("pivoted")

Item     Jan   Feb   Mar
------------------------
Book     330  null  null
Game      50    80  null
Stick   null  null   190

我真的想不出允许我这样做的语法。

编辑说明:这里的主要难点其实是"Not using 'native' PIVOT".

您可能会注意到我有一个子查询来保持月份列的正确顺序。此外,我倾向于更喜欢条件聚合,因为它更容易添加额外的列(即总计)

Declare @Agg varchar(25) = 'SUM'  -- Try Min, Max, Avg, ...

Declare @SQL varchar(max)=''
Select @SQL = @SQL+','+MMM+'='+@Agg+'(case when Month='''+MMM+''' then Price else null end)'
 From (Select MM,MMM From (Values(1,'Jan'),(2,'Feb'),(3,'Mar'),(4,'Apr'),(5,'May'),(6,'Jun'),(7,'Jul'),(8,'Aug'),(9,'Sep'),(10,'Oct'),(11,'Nov'),(12,'Dec')) M(MM,MMM)) A
 Where MMM in (Select Distinct Month from Yourtable)
 Order By MM

Select @SQL='Select Item'+@SQL+' From Yourtable Group By Item'
Exec(@SQL)

Returns

Item    Jan     Feb     Mar
Book    330.00  NULL    NULL
Game    50.00   80.00   NULL
Stick   NULL    NULL    190.00

仅供参考:动态 SQL 生成:

Select Item
      ,Jan=SUM(case when Month='Jan' then Price else null end)
      ,Feb=SUM(case when Month='Feb' then Price else null end)
      ,Mar=SUM(case when Month='Mar' then Price else null end) 
 From Yourtable 
 Group By Item