SQL Server 2005, turn columns into rows

后端 未结 6 925
广开言路
广开言路 2020-12-10 06:50

I am trying to turn a table 90 degrees: make columns rows. No PIVOT is allowed since PIVOT requires aggregate functions.

Example: I have a table with the columns

相关标签:
6条回答
  • 2020-12-10 07:15

    If you try this solution and get a syntax error try setting the compatability mode of your database via

    ALTER DATABASE myDatabase SET COMPATIBILITY_LEVEL = 90;
    

    This will set the compatability to SQLServer 2005 and the above queries will execute w/o a syntax error.

    0 讨论(0)
  • 2020-12-10 07:16

    I found the solution as the following:

    SELECT 
        ID, DE, EN
    FROM 
        TextTable 
    PIVOT(MAX([text]) FOR ISO IN (DE,EN)) p
    

    It's possible to use PIVOT with MAX aggregating function over the text.

    0 讨论(0)
  • 2020-12-10 07:16
    select 
       t.num_claim_no,
       rtrim (xmlagg (xmlelement (e, t.txt_remarks ||'@'|| t.dat_update_date || '  ,  ')).extract ('//text()'), ',') Remarks,
       rtrim (xmlagg (xmlelement (e, t.num_update_no || ' , ')).extract ('//text()'), ',') SrlNo
    from 
       gc_clm_gen_info t
       where t.txt_remarks is not null
      group by 
       t.num_claim_no
    ;
    
    0 讨论(0)
  • 2020-12-10 07:17

    Query without a PIVOT even though other answers prove you can use a PIVOT :)

    SELECT
        MAX(DE.Text) AS DE,
        MAX(EN.Text) AS EN  
    FROM TextTable AS TT
    LEFT JOIN TextTable AS DE
        ON DE.ID = TT.ID
        AND DE.ISO = 'DE'
    LEFT JOIN TextTable AS EN
        ON EN.ID = TT.ID
        AND EN.ISO = 'EN'
    
    0 讨论(0)
  • 2020-12-10 07:32

    Since you explicitly asked for a non-pivot solution: this should work, if you know which ISOs you will have in the rows. I called the table "Test".

    declare @temp table ([ID] int, [de] varchar(255), [en] varchar(255)) -- add ISOs if necessary
    
    INSERT @temp 
    SELECT distinct [ID], '', '' from Test -- ADD '' for other ISOs if necessary
    
    DECLARE c CURSOR read_only 
    FOR SELECT [ID], [ISO], [Text] from test
    
    DECLARE  @ID int, @ISO char(2), @Text varchar(255)
    OPEN c
    
    FETCH NEXT FROM c INTO @ID, @ISO, @Text
    WHILE (@@fetch_status <> -1)
    BEGIN
        IF (@@fetch_status <> -2)
        BEGIN
            UPDATE  @temp
            SET     [DE] = case when @ISO = 'DE' then @Text else [de] end,
                [EN] = case when @ISO = 'EN' then @Text else [en] end
                        -- add ISOs if necessary
            WHERE   [ID] = @ID
        END
        FETCH NEXT FROM c INTO @ID, @ISO, @Text
    END
    
    CLOSE c
    DEALLOCATE c
    
    SELECT * FROM @temp
    
    0 讨论(0)
  • 2020-12-10 07:39

    This answer is really frantisek's, I'm just copying here to correct the mistake (I can't edit directly).

    Basically, you use that solution, with a tweak:

    SELECT 
        max(DE) as DE, max(EN) as EN 
    FROM 
        test 
    PIVOT (MAX([text]) FOR ISO in (DE,EN)) p
    

    This will get the content into a single row. Also, it drops the ID, since it doesn't make sense if you want a single row (there is no logic to indicate what to do with it when combining into a single row).

    Also, the assumption is made that the values in the ISO column are unique, otherwise, this will lose data due to the MAX aggregate.

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