how to convert row to column in SQL

前端 未结 3 1523
北荒
北荒 2021-01-23 20:05

Can somebody help me with this SQL Query.

In the following table, RESPONSES counts how many times SEGMENT has responded on CHECKED date.

CREATE TABLE #         


        
相关标签:
3条回答
  • 2021-01-23 20:24
    Select Checked
        , Sum( Case When Segment = 'A' Then 1 Else 0 End ) As A
        , Sum( Case When Segment = 'B' Then 1 Else 0 End ) As B
        , Sum( Case When Segment = 'C' Then 1 Else 0 End ) As C
    From #Test
    Group By Checked
    

    This type of query is often called a crosstab query. The above solution assumes you want to statically declare which columns you want to see. If you want to dynamically determine the columns, then what you seek is a dynamic crosstab and it cannot be done natively in the SQL language. The SQL language was not designed for dynamic column generation. The solution is to build the query in your middle-tier.

    0 讨论(0)
  • 2021-01-23 20:27

    Please see this on StackOverFlow: If using SQL Server 2005 or greater...

    DECLARE  @test TABLE
    (
        ID INT, 
        SEGMENT CHAR(1),
        RESPONSES INT,
        CHECKED SMALLDATETIME
    )
    
    INSERT INTO @test VALUES (1,'A',0,'2009-05-01')
    INSERT INTO @test VALUES (2,'B',1,'2009-05-01')
    INSERT INTO @test VALUES (3,'C',0,'2009-05-01')
    INSERT INTO @test VALUES (4,'A',0,'2009-05-02')
    INSERT INTO @test VALUES (5,'B',2,'2009-05-02')
    INSERT INTO @test VALUES (6,'C',1,'2009-05-02')
    INSERT INTO @test VALUES (7,'A',1,'2009-05-03')
    INSERT INTO @test VALUES (8,'B',0,'2009-05-03')
    INSERT INTO @test VALUES (9,'C',2,'2009-05-03')
    
    
    SELECT * FROM 
    (    
        SELECT  SEGMENT,
                RESPONSES,
                CHECKED
        FROM @test
    ) AS subquery 
    PIVOT 
    (
        SUM(responses) 
        FOR SEGMENT IN ([a],[b],[c])
    ) AS pivotquery
    

    Dynamic SQL Example

    CREATE TABLE ##test
    (
        ID INT, 
        SEGMENT CHAR(1),
        RESPONSES INT,
        CHECKED SMALLDATETIME
    )
    
    INSERT INTO ##test VALUES (1,'A',0,'2009-05-01')
    INSERT INTO ##test VALUES (2,'B',1,'2009-05-01')
    INSERT INTO ##test VALUES (3,'C',0,'2009-05-01')
    INSERT INTO ##test VALUES (4,'A',0,'2009-05-02')
    INSERT INTO ##test VALUES (5,'B',2,'2009-05-02')
    INSERT INTO ##test VALUES (6,'C',1,'2009-05-02')
    INSERT INTO ##test VALUES (7,'A',1,'2009-05-03')
    INSERT INTO ##test VALUES (8,'B',0,'2009-05-03')
    INSERT INTO ##test VALUES (9,'C',2,'2009-05-03')
    
    DECLARE @SQLa VARCHAR(255),
            @SQLb VARCHAR(255),
            @SQLc VARCHAR(255)
    
    SET @SQLa =
    'SELECT * FROM 
    (    
        SELECT  SEGMENT,
                RESPONSES,
                CHECKED
        FROM ##test
    ) AS subquery 
    PIVOT 
    (
        SUM(responses) 
        FOR SEGMENT IN ('
    
    SET @SQLc = ')
    ) AS pivotquery'
    
    SELECT @sqlB = STUFF(
    (
        SELECT ',[' + SEGMENT + ']'
        FROM ##test WITH (NOLOCK)
        GROUP BY SEGMENT
        FOR XML PATH('')
    ),1, 1, '')
    
    EXECUTE (@SQLa + @SQLb + @SQLc)
    
    DROP TABLE ##test
    
    0 讨论(0)
  • 2021-01-23 20:30

    You need to use dynamic SQL. See this blog post for an example. Another example, different blog, same approach.

    If your columns are static and you're using SQL Server 2005 and higher you can use the PIVOT feature to perform this type of query.

    0 讨论(0)
提交回复
热议问题