不使用PIVOT操作员执行枢轴

时间:2016-11-19 13:15:22

标签: sql sql-server pivot pivot-table

我在设计程序时遇到困难,该程序将使用后面给出的给定聚合执行数据透视表。过程应动态使用传递给过程的聚合来获取Sales.Month和数据透视表中的所有条目,例如,如果我们在Sales上传递SUM(使用VARCHAR传递然后在动态创建的查询上执行EXEC) :

销售:

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

总计:(“转动”)

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

我无法提出允许我这样做的语法。

编辑注释:这里的主要困难实际上是“不使用'本地'PIVOT”。

1 个答案:

答案 0 :(得分:4)

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

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)

返回

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