从 SQL 输出中删除所有值为 0 的列
Remove columns from SQL output where all values are 0
所以,
我对 SQL 中的 PIVOT 不是很好(因为我通常在 Excel 中使用 "flat" 数据这样做),但设法拼凑了以下输出:
CONTID FULLNAME %! %% %3
001 Store 1 0 0 0
002 Store 2 0 0 0
003 Store 3 0 0 0
004 Store 4 0 0 0
005 Store 5 0 0 0
(希望能正常显示)
这是我的 SQL:
USE mydb
go
WITH basequery
AS (SELECT c.contid,
p.fullname,
h.keyalm
FROM customer c
LEFT JOIN clogs h
ON c.serialno = h.serialno
LEFT JOIN contact P
ON c.serialno = P.serialno
WHERE evtype = 1
AND p.conttype = 1)
SELECT *
FROM basequery
PIVOT(Count(keyalm)
FOR keyalm IN ("%!",
"%%",
"%3",
"%4",
"%6",
"%8",
"%9",
"%A",
"%B",
"%C",
"%D",
"%E",
"%F",
"%G",
"%H",
"%I",
"%K",
"%L",
"%M",
"%O",
"%P",
"%Q",
"%R",
"%S",
"%T",
"%U",
"%V",
"%W",
"%X")) AS pvt --I truncated some of this
我想要的是以某种方式不显示总计为 0 的列,就像此处显示的那样。试图在枢轴后做一个 "WHERE",但我为此大喊大叫。
我出于 SO 目的截断了这些列,但我的输出实际上有大约 100 列,而且大多数都是 0。如果可能的话,想从显示的枢轴中消除那些。有没有正确的方法来做到这一点?
如果我没看错,你指望的是 keyalm,并且你想消除展开列由 0 组成的所有行。这意味着对于 contid 和 fullname 的特定组合(分组列由 elimination 标识),clogs 中没有行。如果是这样,您可以在 cte 中消除此类行。在 cte
中添加新列
Count(keyalm) Over(Partition by contid, fullname) as cnt
并在旋转之前过滤 cte where ctn > 0
。
所以你最终得到这样的结果:
DECLARE @clogs TABLE
(
serialno INT ,
keyalm NVARCHAR(MAX)
)
DECLARE @contact TABLE
(
serialno INT ,
fullname NVARCHAR(MAX)
)
DECLARE @customer TABLE
(
contid INT ,
serialno INT
)
INSERT INTO @customer
VALUES ( 1, 10 ),
( 2, 20 ),
( 3, 30 )
INSERT INTO @contact
VALUES ( 10, 'Michael Jordan' ),
( 20, 'Dennis Rodman' ),
( 30, 'Scottie Pippen' )
INSERT INTO @clogs
VALUES ( 10, '%!' ),
( 10, '%%' ),
( 10, '%3' ),
( 20, '%%' );
WITH basequery
AS ( SELECT c.contid ,
p.fullname ,
h.keyalm ,
COUNT(h.keyalm) OVER ( PARTITION BY c.contid,
p.fullname ) AS cnt
FROM @customer c
LEFT JOIN @clogs h ON c.serialno = h.serialno
LEFT JOIN @contact P ON c.serialno = P.serialno
--WHERE evtype = 1 AND p.conttype = 1
),
wrapper
AS ( SELECT contid ,
fullname ,
keyalm
FROM basequery
WHERE cnt > 0
)
SELECT *
FROM wrapper PIVOT( COUNT(keyalm) FOR keyalm IN ( "%!", "%%", "%3" ) ) AS pvt
输出:
contid fullname %! %% %3
1 Michael Jordan 1 1 1
2 Dennis Rodman 0 1 0
对动态列尝试此查询:
USE mydb
go
declare @str as nvarchar(max),@query as nvarchar(max);
set @str = stuff((SELECT distinct ',['+keyalm+']' FROM customer c
LEFT JOIN clogs h
ON c.serialno = h.serialno
LEFT JOIN contact P
ON c.serialno = P.serialno
WHERE evtype = 1
AND p.conttype = 1 for xml path('')),1,1,'')
set @query =
'WITH basequery
AS (SELECT c.contid,
p.fullname,
h.keyalm
FROM customer c
LEFT JOIN clogs h
ON c.serialno = h.serialno
LEFT JOIN contact P
ON c.serialno = P.serialno
WHERE evtype = 1
AND p.conttype = 1)
SELECT *
FROM basequery
PIVOT(Count(keyalm)
FOR keyalm IN ('+ @str +')) AS pvt'
execute sp_executesql @query
所以, 我对 SQL 中的 PIVOT 不是很好(因为我通常在 Excel 中使用 "flat" 数据这样做),但设法拼凑了以下输出:
CONTID FULLNAME %! %% %3
001 Store 1 0 0 0
002 Store 2 0 0 0
003 Store 3 0 0 0
004 Store 4 0 0 0
005 Store 5 0 0 0
(希望能正常显示)
这是我的 SQL:
USE mydb
go
WITH basequery
AS (SELECT c.contid,
p.fullname,
h.keyalm
FROM customer c
LEFT JOIN clogs h
ON c.serialno = h.serialno
LEFT JOIN contact P
ON c.serialno = P.serialno
WHERE evtype = 1
AND p.conttype = 1)
SELECT *
FROM basequery
PIVOT(Count(keyalm)
FOR keyalm IN ("%!",
"%%",
"%3",
"%4",
"%6",
"%8",
"%9",
"%A",
"%B",
"%C",
"%D",
"%E",
"%F",
"%G",
"%H",
"%I",
"%K",
"%L",
"%M",
"%O",
"%P",
"%Q",
"%R",
"%S",
"%T",
"%U",
"%V",
"%W",
"%X")) AS pvt --I truncated some of this
我想要的是以某种方式不显示总计为 0 的列,就像此处显示的那样。试图在枢轴后做一个 "WHERE",但我为此大喊大叫。
我出于 SO 目的截断了这些列,但我的输出实际上有大约 100 列,而且大多数都是 0。如果可能的话,想从显示的枢轴中消除那些。有没有正确的方法来做到这一点?
如果我没看错,你指望的是 keyalm,并且你想消除展开列由 0 组成的所有行。这意味着对于 contid 和 fullname 的特定组合(分组列由 elimination 标识),clogs 中没有行。如果是这样,您可以在 cte 中消除此类行。在 cte
中添加新列Count(keyalm) Over(Partition by contid, fullname) as cnt
并在旋转之前过滤 cte where ctn > 0
。
所以你最终得到这样的结果:
DECLARE @clogs TABLE
(
serialno INT ,
keyalm NVARCHAR(MAX)
)
DECLARE @contact TABLE
(
serialno INT ,
fullname NVARCHAR(MAX)
)
DECLARE @customer TABLE
(
contid INT ,
serialno INT
)
INSERT INTO @customer
VALUES ( 1, 10 ),
( 2, 20 ),
( 3, 30 )
INSERT INTO @contact
VALUES ( 10, 'Michael Jordan' ),
( 20, 'Dennis Rodman' ),
( 30, 'Scottie Pippen' )
INSERT INTO @clogs
VALUES ( 10, '%!' ),
( 10, '%%' ),
( 10, '%3' ),
( 20, '%%' );
WITH basequery
AS ( SELECT c.contid ,
p.fullname ,
h.keyalm ,
COUNT(h.keyalm) OVER ( PARTITION BY c.contid,
p.fullname ) AS cnt
FROM @customer c
LEFT JOIN @clogs h ON c.serialno = h.serialno
LEFT JOIN @contact P ON c.serialno = P.serialno
--WHERE evtype = 1 AND p.conttype = 1
),
wrapper
AS ( SELECT contid ,
fullname ,
keyalm
FROM basequery
WHERE cnt > 0
)
SELECT *
FROM wrapper PIVOT( COUNT(keyalm) FOR keyalm IN ( "%!", "%%", "%3" ) ) AS pvt
输出:
contid fullname %! %% %3
1 Michael Jordan 1 1 1
2 Dennis Rodman 0 1 0
对动态列尝试此查询:
USE mydb
go
declare @str as nvarchar(max),@query as nvarchar(max);
set @str = stuff((SELECT distinct ',['+keyalm+']' FROM customer c
LEFT JOIN clogs h
ON c.serialno = h.serialno
LEFT JOIN contact P
ON c.serialno = P.serialno
WHERE evtype = 1
AND p.conttype = 1 for xml path('')),1,1,'')
set @query =
'WITH basequery
AS (SELECT c.contid,
p.fullname,
h.keyalm
FROM customer c
LEFT JOIN clogs h
ON c.serialno = h.serialno
LEFT JOIN contact P
ON c.serialno = P.serialno
WHERE evtype = 1
AND p.conttype = 1)
SELECT *
FROM basequery
PIVOT(Count(keyalm)
FOR keyalm IN ('+ @str +')) AS pvt'
execute sp_executesql @query