从SQL输出中删除所有值均为0的列

时间:2015-01-31 21:00:18

标签: sql sql-server pivot

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。如果可能,想要从显示的枢轴中消除那些。有没有正确的方法来做到这一点?

2 个答案:

答案 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