Simplify Dynamic SQL Pivot Table

后端 未结 2 537
旧巷少年郎
旧巷少年郎 2020-12-21 22:48

I have written a Dynamic Pivot Table Query based on the following. Here is a SQL FIDDLE for reference.

CREATE TABLE TestTable1 ([idnumber] INT, [DataTypeId]         


        
相关标签:
2条回答
  • 2020-12-21 23:31

    You can shorten your code considerably. First, you can just use count to aggregate the data in the PIVOT. There is no need for the inner count to aggregate the data or the HAVING clause. Finally, you only need to create the list of columns once. You could easily improve the code to:

    DECLARE @cols AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX)
    
    select @cols = STUFF((SELECT ',' + QUOTENAME(DataTypeId) 
                        from TestTable1
                        group by DataTypeId
                        order by DataTypeId
                FOR XML PATH(''), TYPE
                ).value('.', 'NVARCHAR(MAX)') 
            ,1,1,'')
    
    set @query 
          = N'SELECT idnumber, ' + @cols + N' 
              from 
              (
                select idnumber, DataTypeId
                from TestTable1
              ) x
              pivot 
              (
                count(DataTypeId)
                for DataTypeId in (' + @cols + N')
              ) p '
    
    exec sp_executesql @query;
    

    See SQL Fiddle with Demo. This gives the same result:

    | IDNUMBER | 108 | 109 | 110 | 111 |
    |----------|-----|-----|-----|-----|
    |        1 |   3 |   2 |   1 |   1 |
    |        2 |   2 |   0 |   1 |   0 |
    |        3 |   1 |   0 |   0 |   0 |
    |        4 |   2 |   0 |   1 |   1 |
    
    0 讨论(0)
  • 2020-12-21 23:32

    Try replacing it with this.

    SET NOCOUNT ON
    IF OBJECT_ID('TestTable1') IS NOT NULL
    DROP TABLE TestTable1
    GO
    
    CREATE TABLE TestTable1 ([idnumber] INT, [DataTypeId] INT)
    GO
    
    INSERT INTO TestTable1 VALUES 
    (1, 108),(1, 108),(1, 108),(2, 108),(2, 108),
    (3, 108),(1, 109),(1, 109),(1, 110),(2, 110),
    (1, 111),(4, 108),(4, 108),(4, 110),(4, 111)
    
    DECLARE
        @AllColumns NVARCHAR(MAX)
    
    SELECT @AllColumns = ''
    
    SELECT @AllColumns = @AllColumns +
      '[' + CAST(DataTypeId as NVARCHAR)+'],' 
    FROM TestTable1
    GROUP BY DataTypeId
    
    
    SET @AllColumns = LEFT(@AllColumns,LEN(@AllColumns)-1)
    PRINT @AllColumns
    
    0 讨论(0)
提交回复
热议问题