sql >> データベース >  >> RDS >> Sqlserver

SQL Server:カスタム列名を使用したピボット

    これを行うにはいくつかの方法があります。

    質問/回答の数がわかっている場合は、 row_number()を使用できます。 集計関数とCASE式とともに:

    select id,
      max(case when rn = 1 then question end) question1,
      max(case when rn = 1 then answer end) answer1,
      max(case when rn = 2 then question end) question2,
      max(case when rn = 2 then answer end) answer2,
      max(case when rn = 3 then question end) question3,
      max(case when rn = 3 then answer end) answer3
    from
    (
      select id, question, answer,
        row_number() over(partition by id order by id, question) rn
      from yt
    ) src
    group by id;
    

    SQL Fiddle withDemo を参照してください。

    もう1つの提案は、UNPIVOT関数とPIVOT関数の両方を使用して結果を取得することです。 UNPIVOTはあなたの質問を受け取ります およびanswer 列を作成し、それらを複数の行に変換します。

    UNPIVOTの基本的な構文は次のとおりです。

    select id,
      col+cast(rn as varchar(10)) col,
      value
    from
    (
      -- when you perform an unpivot the datatypes have to be the same. 
      -- you might have to cast the datatypes in this query
      select id, question, cast(answer as varchar(500)) answer,
        row_number() over(partition by id order by id, question) rn
      from yt
    ) src
    unpivot
    (
      value
      for col in (question, answer)
    ) unpiv;
    

    デモ を参照してください。 。これにより、結果が得られます:

    |      ID |       COL |                                VALUE |
    --------------------------------------------------------------
    | 4482515 | question1 | I would like to be informed by mail. |
    | 4482515 |   answer1 |                                   No |
    | 4482515 | question2 |                    Plan to Purchase? |
    | 4482515 |   answer2 |                       Over 12 months |
    | 4482515 | question3 |                   Test Question Text |
    | 4482515 |   answer3 |                          some Answer |
    

    ご覧のとおり、 row_number()を追加しました 値を最初のサブクエリに設定して、各回答を質問に関連付けることができるようにします。これがピボット解除されたら、 questionを使用して新しい列名で結果をピボットできます。 /回答 連結された行番号の値を使用します。 PIVOT構文のコードは次のようになります:

    select id, question1, answer1, question2, answer2,
      question3, answer3
    from
    (
      select id,
        col+cast(rn as varchar(10)) col,
        value
      from
      (
      -- when you perform an unpivot the datatypes have to be the same. 
      -- you might have to cast the datatypes in this query
        select id, question, cast(answer as varchar(500)) answer,
          row_number() over(partition by id order by id, question) rn
        from yt
      ) src
      unpivot
      (
        value
        for col in (question, answer)
      ) unpiv
    ) d
    pivot
    (
      max(value)
      for col in (question1, answer1, question2, answer2,
                  question3, answer3)
    ) piv;
    

    SQL Fiddle withDemo を参照してください。 。今あなたの状況では、あなたは動的な数の質問/回答があると述べました。その場合は、動的SQLを使用して結果を取得する必要があります。

    DECLARE @cols AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX)
    
    select @cols = STUFF((SELECT ',' + QUOTENAME(c.col+cast(rn as varchar(10))) 
                        from 
                        (
                          select row_number() over(partition by id 
                                                   order by id, question) rn
                          from yt
                        ) d
                        cross apply
                        (
                          select 'question' col, 1 sort union all select 'answer', 2
                        ) c
                        group by col, rn, sort
                        order by rn, sort
                FOR XML PATH(''), TYPE
                ).value('.', 'NVARCHAR(MAX)') 
            ,1,1,'')
    
    set @query = 'SELECT id, ' + @cols + '
                  from
                  (
                    select id,
                      col+cast(rn as varchar(10)) col,
                      value
                    from
                    (
                     -- when you perform an unpivot the datatypes have to be the same. 
                     -- you might have to cast the datatypes in this query
                      select id, question, cast(answer as varchar(500)) answer,
                        row_number() over(partition by id order by id, question) rn
                      from yt
                    ) src
                    unpivot
                    (
                      value
                      for col in (question, answer)
                    ) unpiv
                  ) d
                  pivot 
                  (
                      max(value)
                      for col in (' + @cols + ')
                  ) p '
    
    execute(@query);
    

    SQL Fiddle withDemo を参照してください。 。これらは結果をもたらします:

    |      ID |                            QUESTION1 | ANSWER1 |         QUESTION2 |        ANSWER2 |          QUESTION3 |     ANSWER3 |
    ------------------------------------------------------------------------------------------------------------------------------------
    | 4482515 | I would like to be informed by mail. |      No | Plan to Purchase? | Over 12 months | Test Question Text | some Answer |
    



    1. Oracleのデッドロック

    2. カスタム区切り文字で非常に大きな文字列を分割しますか?

    3. 日付フィールドに対して日時フィールドを照会するための最良の方法は何ですか?

    4. 重複した行をすべて表示