将另一列添加到 SQL 服务器数据透视表 table

Adding another column to the SQL Server pivot table

下面的主元table只查询returns一列。我如何添加另一列,例如 name

   Select 
   isnull (Definition_, 'GrandTotal') AS 'Definition_',
   isnull (SUM(CASE DATEPART(MONTH,DueDate) WHEN 1 THEN OrderQty END),0) AS January,
   isnull (SUM(CASE DATEPART(MONTH,DueDate) WHEN 2 THEN OrderQty END),0) AS Feburary, 
   isnull (SUM(CASE DATEPART(MONTH,DueDate) WHEN 3 THEN OrderQty END),0) AS March,    
   isnull (SUM(CASE DATEPART(MONTH,DueDate) WHEN 4 THEN OrderQty END),0) AS April,    
   isnull (SUM(CASE DATEPART(MONTH,DueDate) WHEN 5 THEN OrderQty END),0) AS May,      
   isnull (SUM(CASE DATEPART(MONTH,DueDate) WHEN 6 THEN OrderQty END),0) AS June,  
   isnull (SUM(CASE DATEPART(MONTH,DueDate) WHEN 7 THEN OrderQty END),0) AS July,
   isnull (SUM(CASE DATEPART(MONTH,DueDate) WHEN 8 THEN OrderQty END),0) AS August,
   isnull (SUM(CASE DATEPART(MONTH,DueDate) WHEN 9 THEN OrderQty END),0) AS September,
   isnull (SUM(CASE DATEPART(MONTH,DueDate) WHEN 10 THEN OrderQty END),0) AS October,
   isnull (SUM(CASE DATEPART(MONTH,DueDate) WHEN 11 THEN OrderQty END),0) AS November,
   isnull (SUM(CASE DATEPART(MONTH,DueDate) WHEN 12 THEN OrderQty END),0) AS December,
   isnull (SUM(OrderQty),0) AS GrandTotal,
    
    FROM Production.WorkOrder
    GROUP BY GROUPING SETS((DATEPART(YEAR, DueDate), Definition_, ProductID),
    ())order by ProductID;

下面是一个使用 pivot 的例子,应该会产生预期的结果:

DECLARE @t TABLE(
  Definition_ VARCHAR(100)
 ,DueDate DATE
 ,OrderQty INT
);

INSERT INTO @t VALUES
 ('Test1', '2021-01-01', 2)
,('Test1', '2021-01-02', 3)
,('Test1', '2021-01-17', 5)
,('Test1', '2021-02-15', 4)
,('Test1', '2021-02-18', 6)
,('Test1', '2021-10-15', 4)
,('Test1', '2021-12-18', 6);

WITH cteMonth AS(
  SELECT isnull (Definition_, 'GrandTotal') AS 'Definition_'
      ,OrderQty
      ,CASE(DATEPART(MONTH, DueDate))
         WHEN 1 THEN 'January'
         WHEN 2 THEN 'February'
         WHEN 3 THEN 'March'
         WHEN 4 THEN 'April'
         WHEN 5 THEN 'May'
         WHEN 6 THEN 'June'
         WHEN 7 THEN 'July'
         WHEN 8 THEN 'August'
         WHEN 9 THEN 'September'
         WHEN 10 THEN 'October'
         WHEN 11 THEN 'November'
         WHEN 12 THEN 'December'
       END As Month_
  FROM @t
),
ctePivot AS(
SELECT *
  FROM cteMonth
  PIVOT (SUM(OrderQty) FOR Month_ IN ([January],[February],[March],[April],[May],[June],[July],[August],[September],[October],[November],[December])) as p
)
SELECT [Definition_]
      ,ISNULL([January], 0) + ISNULL([February], 0) + ISNULL([March], 0) + ISNULL([April], 0) + ISNULL([May], 0) + ISNULL([June], 0) +
        ISNULL([July], 0) + ISNULL([August], 0) + ISNULL([September], 0) + ISNULL([October], 0) + ISNULL([November], 0) + ISNULL([December], 0) AS GrandTotal
      ,ISNULL([January], 0) [January]
      ,ISNULL([February], 0) [February]
      ,ISNULL([March], 0) [March]
      ,ISNULL([April], 0) [April]
      ,ISNULL([May], 0) [May]
      ,ISNULL([June], 0) [June]
      ,ISNULL([July], 0) [July]
      ,ISNULL([August], 0) [August]
      ,ISNULL([September], 0) [September]
      ,ISNULL([October], 0) [October]
      ,ISNULL([November], 0) [November]
      ,ISNULL([December], 0) [December]
  FROM ctePivot

并且在枢轴之前计算 GrandTotal:

DECLARE @t TABLE(
  Definition_ VARCHAR(100)
 ,DueDate DATE
 ,OrderQty INT
);

INSERT INTO @t VALUES
 ('Test1', '2021-01-01', 2)
,('Test1', '2021-01-02', 3)
,('Test1', '2021-01-17', 5)
,('Test1', '2021-02-15', 4)
,('Test1', '2021-02-18', 6)
,('Test1', '2021-10-15', 4)
,('Test1', '2021-12-18', 6);

WITH cteMonth AS(
  SELECT isnull (Definition_, 'GrandTotal') AS 'Definition_'
      ,OrderQty
      ,SUM(OrderQty) OVER (PARTITION BY ISNULL(Definition_, 'GrandTotal')) AS GrandTotal
      ,CASE(DATEPART(MONTH, DueDate))
         WHEN 1 THEN 'January'
         WHEN 2 THEN 'February'
         WHEN 3 THEN 'March'
         WHEN 4 THEN 'April'
         WHEN 5 THEN 'May'
         WHEN 6 THEN 'June'
         WHEN 7 THEN 'July'
         WHEN 8 THEN 'August'
         WHEN 9 THEN 'September'
         WHEN 10 THEN 'October'
         WHEN 11 THEN 'November'
         WHEN 12 THEN 'December'
       END As Month_
  FROM @t
),
ctePivot AS(
SELECT *
  FROM cteMonth
  PIVOT (SUM(OrderQty) FOR Month_ IN ([January],[February],[March],[April],[May],[June],[July],[August],[September],[October],[November],[December])) as p
)
SELECT [Definition_]
      ,GrandTotal
      ,ISNULL([January], 0) [January]
      ,ISNULL([February], 0) [February]
      ,ISNULL([March], 0) [March]
      ,ISNULL([April], 0) [April]
      ,ISNULL([May], 0) [May]
      ,ISNULL([June], 0) [June]
      ,ISNULL([July], 0) [July]
      ,ISNULL([August], 0) [August]
      ,ISNULL([September], 0) [September]
      ,ISNULL([October], 0) [October]
      ,ISNULL([November], 0) [November]
      ,ISNULL([December], 0) [December]
  FROM ctePivot

看来您只需要将 NAME 添加到分组中:

You should use the GROUPING() function to check for the total row, instead of ISNULL

Select 
   Definition_ AS [Definition_],
   CASE WHEN GROUPING(NAME) = 0 THEN NAME ELSE 'GrandTotal' END AS NAME,
   isnull (SUM(CASE DATEPART(MONTH,DueDate) WHEN 1 THEN OrderQty END),0) AS January,
   isnull (SUM(CASE DATEPART(MONTH,DueDate) WHEN 2 THEN OrderQty END),0) AS Feburary, 
   isnull (SUM(CASE DATEPART(MONTH,DueDate) WHEN 3 THEN OrderQty END),0) AS March,    
   isnull (SUM(CASE DATEPART(MONTH,DueDate) WHEN 4 THEN OrderQty END),0) AS April,    
   isnull (SUM(CASE DATEPART(MONTH,DueDate) WHEN 5 THEN OrderQty END),0) AS May,      
   isnull (SUM(CASE DATEPART(MONTH,DueDate) WHEN 6 THEN OrderQty END),0) AS June,  
   isnull (SUM(CASE DATEPART(MONTH,DueDate) WHEN 7 THEN OrderQty END),0) AS July,
   isnull (SUM(CASE DATEPART(MONTH,DueDate) WHEN 8 THEN OrderQty END),0) AS August,
   isnull (SUM(CASE DATEPART(MONTH,DueDate) WHEN 9 THEN OrderQty END),0) AS September,
   isnull (SUM(CASE DATEPART(MONTH,DueDate) WHEN 10 THEN OrderQty END),0) AS October,
   isnull (SUM(CASE DATEPART(MONTH,DueDate) WHEN 11 THEN OrderQty END),0) AS November,
   isnull (SUM(CASE DATEPART(MONTH,DueDate) WHEN 12 THEN OrderQty END),0) AS December,
   isnull (SUM(OrderQty),0) AS GrandTotal
    
FROM Production.WorkOrder
GROUP BY GROUPING SETS(
    (DATEPART(YEAR, DueDate), Definition_, NAME, ProductID),
    ()
)
order by ProductID;

不清楚您为什么不同时选择 DATEPART(YEAR, DueDate)ProductID