如何在动态数据透视表中使用 NULL 值进行 GROUP BY
How to GROUP BY with NULL values in dynamic pivot
这是我的查询示例:
IF OBJECT_ID('tempdb..##A') IS NOT NULL DROP TABLE ##A
IF OBJECT_ID('tempdb..#table1') IS NOT NULL DROP TABLE #table1
Create table #Table1 ( ControlNo INT, Line varchar(50), Profit INT, Code varchar(50) )
INSERT INTO #Table1 (ControlNo, Line, Profit, Code)
VALUES (1111,'Line1',NULL,NULL),
(1111,'Line2',100,'A'),
(3333,'Line1',200,'C'),
(4444,'Line1',50,'B'),
(4444,'Line2',100,NULL)
DECLARE @columns AS NVARCHAR(MAX),
@finalquery AS NVARCHAR(MAX);
SET @columns = STUFF((SELECT distinct ',' + QUOTENAME(Line) FROM #Table1 FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'')
set @finalquery = '
select p.ControlNo,
p.Code,' + @columns + '
from ( select ControlNo, Line, Code, Profit
from #Table1
)a
pivot
(
SUM(Profit)
for Line IN (' + @columns + ')
)p
ORDER BY ControlNo
'
exec(@finalquery)
结果中包含 NULL
的行。
ControlNo Code Line1 Line2
1111 NULL NULL NULL
1111 A NULL 100
3333 C 200 NULL
4444 NULL NULL 100
4444 B 50 NULL
所需的输出需要是这样的:
看起来常规条件聚合在这里效果更好,因为 Code
似乎只是 MIN(Code)
每个 ControlNo
DECLARE @columns nvarchar(max) =
STUFF((SELECT distinct
',ISNULL(SUM(CASE WHEN Line = ' + QUOTENAME(Line, '''') + ' THEN Profit END), 0) ' + QUOTENAME(Line)
FROM #Table1
FOR XML PATH(''), TYPE
).value('text()[1]', 'NVARCHAR(MAX)') ,1 , LEN(','),'');
DECLARE @finalquery nvarchar(max)= N'
SELECT
t.ControlNo,
MIN(t.Code) Code,
' + @columns + '
from #Table1 t
GROUP BY
t.ControlNo
ORDER BY ControlNo;
';
PRINT @finalquery; -- for testing
EXEC sp_executesql
@finalquery;
这是我的查询示例:
IF OBJECT_ID('tempdb..##A') IS NOT NULL DROP TABLE ##A
IF OBJECT_ID('tempdb..#table1') IS NOT NULL DROP TABLE #table1
Create table #Table1 ( ControlNo INT, Line varchar(50), Profit INT, Code varchar(50) )
INSERT INTO #Table1 (ControlNo, Line, Profit, Code)
VALUES (1111,'Line1',NULL,NULL),
(1111,'Line2',100,'A'),
(3333,'Line1',200,'C'),
(4444,'Line1',50,'B'),
(4444,'Line2',100,NULL)
DECLARE @columns AS NVARCHAR(MAX),
@finalquery AS NVARCHAR(MAX);
SET @columns = STUFF((SELECT distinct ',' + QUOTENAME(Line) FROM #Table1 FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'')
set @finalquery = '
select p.ControlNo,
p.Code,' + @columns + '
from ( select ControlNo, Line, Code, Profit
from #Table1
)a
pivot
(
SUM(Profit)
for Line IN (' + @columns + ')
)p
ORDER BY ControlNo
'
exec(@finalquery)
结果中包含 NULL
的行。
ControlNo Code Line1 Line2
1111 NULL NULL NULL
1111 A NULL 100
3333 C 200 NULL
4444 NULL NULL 100
4444 B 50 NULL
所需的输出需要是这样的:
看起来常规条件聚合在这里效果更好,因为 Code
似乎只是 MIN(Code)
每个 ControlNo
DECLARE @columns nvarchar(max) =
STUFF((SELECT distinct
',ISNULL(SUM(CASE WHEN Line = ' + QUOTENAME(Line, '''') + ' THEN Profit END), 0) ' + QUOTENAME(Line)
FROM #Table1
FOR XML PATH(''), TYPE
).value('text()[1]', 'NVARCHAR(MAX)') ,1 , LEN(','),'');
DECLARE @finalquery nvarchar(max)= N'
SELECT
t.ControlNo,
MIN(t.Code) Code,
' + @columns + '
from #Table1 t
GROUP BY
t.ControlNo
ORDER BY ControlNo;
';
PRINT @finalquery; -- for testing
EXEC sp_executesql
@finalquery;