SQL Server 2008 R2:带有where和having子句的数据透视表的动态查询

时间:2014-11-22 12:39:11

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

注意:此帖子与之前的帖子略有不同。

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

示例

表:测试

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

2 个答案:

答案 0 :(得分:2)

你可以用这个:

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)  

答案 1 :(得分:-1)

试试这个。

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 

输出:

(输入字符串&#39; A1,A2&#39;)

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

(对于输入字符串&#39; A1&#39;)

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