【问题标题】:SQL Server 2008 R2: Dynamic query for pivot table with where and having clauseSQL Server 2008 R2:使用 where 和 having 子句对数据透视表进行动态查询
【发布时间】:2014-11-22 12:39:10
【问题描述】:

注意:本帖与上一帖略有不同。

我有下表,详细信息如下示例所示。

示例

表格:测试

create table test
(
 cola varchar(10),
 colb varchar(10),
 colc varchar(10)
);

插入

insert into test values('101','1234','A1');
insert into test values('101','4321','A2');
insert into test values('201','5678','A3');
insert into test values('301','8765','A4');
insert into test values('401','9877','A1');
 insert into test values('101','9997','A6');
 insert into test values('201','2277','A1');
 insert into test values('201','1577','A5'); 

注意:现在我只想显示cola 属于colc 值的记录。如果用户将colc 值作为参数传递给存储过程,则它必须匹配colc 的确切值属于哪个cola 值。

预期结果

如果用户通过A1,A2,A6 那么结果应该是:

cola   A1   A2   A6
--------------------
101    1      1     1

注意:在上面的结果中,记录101出现是因为它属于A1,A2,A6而不是其他值。 201 不会出现,因为它也属于 A1,A3A5

如果用户通过A1 那么结果应该是:

cola   A1 
--------
401    1  

注意:在上面的结果中,记录401出现是因为它属于A1

我的尝试:

透视查询

DECLARE @Stuff varchar(max) = 'A1'
DECLARE @Sql varchar(max)

SET @Sql = 'SELECT cola,' +@Stuff+ '
            from
            (
                select cola,colc
                from test 
                where colc in(''A1'')
                group by cola,colc
                having count(distinct colc) = 1

            )p
            PIVOT
            (
                COUNT(colc)
                FOR colc IN ('+@Stuff+')
            )AS pvt'

PRINT(@Sql)
EXEC(@Sql)      

获取结果

cola    A1  
----------
101     1
401     1

你可以去这里练习一下:

SQL 小提琴:

http://sqlfiddle.com/#!3/9b1fd/4

【问题讨论】:

    标签: sql-server sql-server-2008-r2 pivot


    【解决方案1】:

    你可以用这个:

    DECLARE @Stuff varchar(max) = 'A1'
            DECLARE @Sql varchar(max)
        DECLARE @totalparam int = 1
            SET @Sql = 'SELECT cola,' +@Stuff+ '
                        from
                        (
                            select cola,colc
                            from test a
                            where colc in(''A1'')
                            group by cola,colc
                            having (select count(colc) from test b where b.cola = a.cola )  = @totalparam
    
                        )p
                    PIVOT
                    (
                        COUNT(colc)
                        FOR colc IN ('+@Stuff+')
                    )AS pvt'
    
        PRINT(@Sql)
        EXEC(@Sql)  
    

    【讨论】:

    • 这不符合预期结果。请重新检查。
    • 对不起.. 我的意思是这段代码:sqlfiddle.com/#!3/9b1fd/72 你可以修改它以将 totalparam 设置为参数。
    • 不!完全错误。如果您以A1,A2,A6 的形式提供输入,那么它必须返回记录101 以及详细信息。
    • 是的,确实如此。你检查过结果吗?它在底部。请检查结果。详细信息是 101。此外,您可以修改您的列表和总参数:sqlfiddle.com/#!3/40185/3
    • 如果输入为“A1,A3”,我会优化查询:sqlfiddle.com/#!3/40185/7
    【解决方案2】:

    试试这个。

    DECLARE @Stuff VARCHAR(max) = 'A1,A2'--'A1'
    DECLARE @Sql NVARCHAR(max),
            @cnt INT
    
    SELECT @cnt = Count(1)
    FROM   (SELECT Cast ('<M>' + Replace(@Stuff, ',', '</M><M>') + '</M>' AS XML) AS Data) AS A
           CROSS APPLY Data.nodes ('/M') AS Split(a)
    
    SET @Sql = 'SELECT cola,' + @Stuff+ ' from
                    (SELECT a.cola, a.colc
                     FROM   test a
                     JOIN (SELECT cola
                     FROM   test
                     GROUP  BY cola
                     HAVING Count(DISTINCT colc) = '
               + CONVERT(VARCHAR(30), @cnt)+ ') B
                     ON a.cola = b.cola
                     where colc in (select rtrim(ltrim(Split.a.value(''.'', ''VARCHAR(100)'')))
    FROM   (SELECT Cast (''<M>'' + Replace('''
               + @Stuff + ''', '','', ''</M><M>'') + ''</M>'' AS XML) AS Data) AS A
           CROSS APPLY Data.nodes (''/M'') AS Split(a) )
                    )p
                    PIVOT
                    (COUNT(colc) FOR colc IN (' + @Stuff+ ')
                    )AS pvt'
    
    EXEC Sp_executesql @Sql 
    

    输出:

    (对于输入字符串'A1,A2')

    +-----+----+----+
    |cola | A1 | A2 |
    +-----+----+----+
    |101  | 1  | 1  |
    +-----+----+----+
    

    (对于输入字符串'A1')

    +-----+----+
    |cola | A1 |
    +-----+----+
    |401  | 1  |
    +-----+----+
    

    【讨论】:

    • 谁投了反对票,请评论为什么它没有用。这样我就可以修复
    • 不是我的 DV,而是对代码在做什么以及它为什么起作用的解释将使这成为一个更好的答案。 :)
    • 请通过将这些记录插入表中重新测试您的脚本:101 4234 A5201 3434 A1201 3435 A6。现在通过@stuff = A1,A2,A5。请不要删除以前的记录,也请保留这些记录。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-30
    • 1970-01-01
    相关资源
    最近更新 更多