How to make awkward pivot of sql table in SQL Server 2005?

后端 未结 3 1187
忘掉有多难
忘掉有多难 2021-01-05 08:58

I have to rotate a given table from an SQL Server but a normal pivot just doesn\'t work (as far as i tried). So has anybody an idea how to rotate the table into the desired

相关标签:
3条回答
  • 2021-01-05 09:41

    What you seek is dynamic cross tab. The short answer is that it cannot be done in T-SQL without some fugly dynamic SQL. The Hoyle answer is that you should pivot the data in a reporting tool or in the middle tier.

    0 讨论(0)
  • 2021-01-05 09:49
    select
    id,
    'Numerator' as ValueType,
    case when label = labelNameOne then Numerator else 0 end as LabelNameOne,
    case when label = labelNameTwo then Numerator else 0 end as LabelNameTwo,
    case when label = labelNameTree then Numerator else 0 end as LabelNameTree,
    case when label = labelNameFour then Numerator else 0 end as LabelNameFour,
    case when label = labelNameFive then Numerator else 0 end as LabelNameFive,
    case when label = labelNameSix then Numerator else 0 end as LabelNameSix
    
    union All
    

    ... similar query with Denominator ...

    union all
    

    ... similar query with Ratio...

    0 讨论(0)
  • 2021-01-05 10:01

    This should sort you out. It's really an UNPIVOT and a PIVOT. Note that you have to conform your data because the UNPIVOT puts all the data in the same column.

    Note that I had to recreate/repopulate the table variable in the inner dynamic SQL - typically this is not necessary when dealing with a permanent table.

    SET NOCOUNT ON ;
    
    DECLARE @pivot_cols AS varchar(max) ;
    DECLARE @src AS TABLE
        (
         ID int NOT NULL
        ,Label varchar(14) NOT NULL
        ,Numerator int NOT NULL
        ,Denominator int NOT NULL
        ,Ratio decimal(5, 4) NOT NULL
        ) ;
    
    DECLARE @label_order AS TABLE
        (
         Label varchar(14) NOT NULL
        ,Sort int NOT NULL
        )
    
    INSERT  INTO @src
    VALUES  (1, 'LabelNameOne', 41, 10, 4.1) ;
    INSERT  INTO @src
    VALUES  (1, 'LabelNameTwo', 0, 0, 0) ;
    INSERT  INTO @src
    VALUES  (1, 'LabelNameThree', 21, 10, 2.1) ;
    INSERT  INTO @src
    VALUES  (1, 'LabelNameFour', 15, 10, 1.5) ;
    INSERT  INTO @src
    VALUES  (2, 'LabelNameOne', 19, 19, 1) ;
    INSERT  INTO @src
    VALUES  (2, 'LabelNameTwo', 0, 0, 0) ;
    INSERT  INTO @src
    VALUES  (2, 'LabelNameThree', 15, 16, 0.9375) ;
    INSERT  INTO @src
    VALUES  (2, 'LabelNameFive', 19, 19, 1) ;
    INSERT  INTO @src
    VALUES  (2, 'LabelNameSix', 17, 17, 1) ;
    INSERT  INTO @src
    VALUES  (3, 'LabelNameOne', 12, 12, 1) ;
    INSERT  INTO @src
    VALUES  (3, 'LabelNameTwo', 0, 0, 0) ;
    INSERT  INTO @src
    VALUES  (3, 'LabelNameThree', 11, 12, 0.9167) ;
    INSERT  INTO @src
    VALUES  (3, 'LabelNameFour', 12, 12, 1) ;
    INSERT  INTO @src
    VALUES  (3, 'LabelNameSix', 0, 1, 0) ;
    
    INSERT  INTO @label_order
    VALUES  ('LabelNameOne', 1) ;
    INSERT  INTO @label_order
    VALUES  ('LabelNameTwo', 2) ;
    INSERT  INTO @label_order
    VALUES  ('LabelNameThree', 3) ;
    INSERT  INTO @label_order
    VALUES  ('LabelNameFour', 4) ;
    INSERT  INTO @label_order
    VALUES  ('LabelNameFive', 5) ;
    INSERT  INTO @label_order
    VALUES  ('LabelNameSix', 6) ;
    
    WITH    Labels
              AS (
                  SELECT  DISTINCT
                            src.Label
                           ,ISNULL(label_order.Sort, 0) AS Sort
                  FROM      @src AS src
                  LEFT JOIN @label_order AS label_order
                            ON src.label = label_order.label
                 )
        SELECT  @pivot_cols = COALESCE(@pivot_cols + ',', '') + QUOTENAME(Label, '[')
        FROM    Labels
        ORDER BY Sort
               ,Label ;
    
    DECLARE @template AS varchar(max) ;
    
    SET @template = '
    DECLARE @src AS TABLE
        (
         ID int NOT NULL
        ,Label varchar(14) NOT NULL
        ,Numerator int NOT NULL
        ,Denominator int NOT NULL
        ,Ratio decimal(5, 4) NOT NULL
        ) ;
    
    INSERT  INTO @src
    VALUES  (1, ''LabelNameOne'', 41, 10, 4.1) ;
    INSERT  INTO @src
    VALUES  (1, ''LabelNameTwo'', 0, 0, 0) ;
    INSERT  INTO @src
    VALUES  (1, ''LabelNameThree'', 21, 10, 2.1) ;
    INSERT  INTO @src
    VALUES  (1, ''LabelNameFour'', 15, 10, 1.5) ;
    INSERT  INTO @src
    VALUES  (2, ''LabelNameOne'', 19, 19, 1) ;
    INSERT  INTO @src
    VALUES  (2, ''LabelNameTwo'', 0, 0, 0) ;
    INSERT  INTO @src
    VALUES  (2, ''LabelNameThree'', 15, 16, 0.9375) ;
    INSERT  INTO @src
    VALUES  (2, ''LabelNameFive'', 19, 19, 1) ;
    INSERT  INTO @src
    VALUES  (2, ''LabelNameSix'', 17, 17, 1) ;
    INSERT  INTO @src
    VALUES  (3, ''LabelNameOne'', 12, 12, 1) ;
    INSERT  INTO @src
    VALUES  (3, ''LabelNameTwo'', 0, 0, 0) ;
    INSERT  INTO @src
    VALUES  (3, ''LabelNameThree'', 11, 12, 0.9167) ;
    INSERT  INTO @src
    VALUES  (3, ''LabelNameFour'', 12, 12, 1) ;
    INSERT  INTO @src
    VALUES  (3, ''LabelNameSix'', 0, 1, 0) ;
    
    WITH    src_conformed
              AS (
                  SELECT    ID
                           ,Label
                           ,CAST (Numerator AS decimal(10, 4)) AS Numerator
                           ,CAST (Denominator AS decimal(10, 4)) AS Denominator
                           ,CAST (Ratio AS decimal(10, 4)) AS Ratio
                  FROM      @src
                 ),
            UNPIVOTED
              AS (
                  SELECT    *
                  FROM      src_conformed UNPIVOT ( Val FOR Col IN (Numerator, Denominator, Ratio) ) AS unpvt
                 )
        SELECT  *
        FROM    UNPIVOTED PIVOT ( SUM(Val) FOR Label IN ({@pivot_cols}) ) AS pvt
        ORDER BY ID
               ,Col ;' ;
    
    SET @template = REPLACE(@template, '{@pivot_cols}', @pivot_cols) ;
    
    EXEC (@template) ;
    
    0 讨论(0)
提交回复
热议问题