SO, 我在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。如果可能,想要从显示的枢轴中消除那些。有没有正确的方法来做到这一点?
答案 0 :(得分:0)
如果我说得对,你指望keyalm,你想要消除传播列由0组成的所有行。这意味着对于contid和fullname的特定组合(通过消除来识别分组列),clog中没有行。如果是这样,您可以在cte中消除此类行。在cte中添加新列
Count(keyalm) Over(Partition by contid, fullname) as cnt
并在转动where ctn > 0
之前过滤cte。
所以你最终得到这样的东西:
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
答案 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