将另一列添加到 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
下面的主元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 ofISNULL
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