1

次のデータを含む SQL Server ビューがあります。

ID   clientID  surveyID    questionID     q_optionID   q_ans_text
-----------------------------------------------------------------
1       1          1           1            NULL            Yes
2       1          1           2             18             NULL 
3       1          1           3             19             NULL
4       2          1           1            NULL             No
5       2          1           2             18             NULL
6       2          1           3             19             NULL
7       3          2           1            NULL            Yes 
8       3          2           2             15             NULL 
9       3          2           3             13             NULL   

結果を次のようにしたい:

ClientID  SurveyID   Q1    Q2    Q3  
------------------------------------
   1          1     Yes    18    19   
   2          1      No    18    19   
   3          2     Yes    15    13 

条件NULL値が無視され、適切な答えが列に配置される場所。ピボット テーブルの例を見てきましたが、それらは単一列のピボットに焦点を当てているようです。

4

3 に答える 3

3

この変換を実行するには、データを変換する必要がありUNPIVOTますPIVOT。は、 列UNPIVOTから値を取得し、値と列名を含む 2 つの列に変換します。q_optionIDq_ans_text

これには 2 つの方法がありますPIVOT。静的バージョンを使用してすべての値をハードコーディングする方法と、動的 SQL を使用する方法です。データを取得するにUNPIVOTは、データが同じデータ型であることを確認する必要があるため、変換が必要になる場合があります。

静的ピボット:

select clientid, surveyid, 
    questionid,
    value,
    col
  from
  (
    select clientid, surveyid, questionid,
      cast(q_optionID as varchar(4)) q_optionID,
      q_ans_text
    from yourtable
  ) s
  unpivot
  (
    value
    for col in (q_optionID, q_ans_text)
  ) un

デモで SQL Fiddle を参照してください

アンピボットの結果:

| CLIENTID | SURVEYID | QUESTIONID | VALUE |        COL |
---------------------------------------------------------
|        1 |        1 |          1 |   Yes | q_ans_text |
|        1 |        1 |          2 |    18 | q_optionID |
|        1 |        1 |          3 |    19 | q_optionID |
|        2 |        1 |          1 |    No | q_ans_text |
|        2 |        1 |          2 |    18 | q_optionID |
|        2 |        1 |          3 |    19 | q_optionID |
|        3 |        2 |          1 |   Yes | q_ans_text |
|        3 |        2 |          2 |    15 | q_optionID |
|        3 |        2 |          3 |    13 | q_optionID |

次に、PIVOTを結果に適用して、最終製品を取得します。

select *
from
(
  select clientid, surveyid, 
    'Q'+cast(questionid as varchar(10)) question,
    value
  from
  (
    select clientid, surveyid, questionid,
      cast(q_optionID as varchar(4)) q_optionID,
      q_ans_text
    from yourtable
  ) s
  unpivot
  (
    value
    for col in (q_optionID, q_ans_text)
  ) un
) src
pivot
(
  max(value)
  for question in (Q1, Q2, Q3)
) piv

デモで SQL Fiddle を参照してください

動的ピボット:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME('Q'+cast(questionid as varchar(10))) 
                    from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT clientid, surveyid,' + @cols + ' from 
             (
                select clientid, surveyid, 
                  ''Q''+cast(questionid as varchar(10)) question,
                  value
                from
                (
                  select clientid, surveyid, questionid,
                    cast(q_optionID as varchar(4)) q_optionID,
                    q_ans_text
                  from yourtable
                ) s
                unpivot
                (
                  value
                  for col in (q_optionID, q_ans_text)
                ) un
            ) x
            pivot 
            (
                max(value)
                for question in (' + @cols + ')
            ) p '

execute(@query)

デモで SQL Fiddle を参照してください

UNION ALL/Aggregate with Case バージョン:

今、持っていないシステムで作業している場合は、 toおよび to をPIVOT使用した集約関数を使用できます。UNION ALLUNPIVOTCASEPIVOT

select clientid, surveyid,
  max(case when questionid = 1 then value end) Q1,
  max(case when questionid = 2 then value end) Q2,
  max(case when questionid = 3 then value end) Q3
from
(
  select clientid, surveyid, questionid, cast(q_optionID as varchar(10)) value, 'q_optionID' col
  from yourtable
  union all
  select clientid, surveyid, questionid, q_ans_text value, 'q_ans_text' col
  from yourtable
) unpiv
group by clientid, surveyid

デモで SQL Fiddle を参照してください

3 つすべてで同じ結果が得られます。

| CLIENTID | SURVEYID |  Q1 | Q2 | Q3 |
---------------------------------------
|        1 |        1 | Yes | 18 | 19 |
|        2 |        1 |  No | 18 | 19 |
|        3 |        2 | Yes | 15 | 13 |
于 2012-12-11T22:40:27.063 に答える
1

明示的なアンピボットのない例。ただし、知っておくと非常に便利なテクニックです。

Select
  clientID, 
  SurveyID, 
  [1] as Q1, 
  [2] as Q2,
  [3] as Q3
From (
  Select
    clientID,
    surveyID,
    questionID,
    IsNull(Cast(q_optionID as varchar(10)), q_ans_text) answer
  From
    Answers
) a
Pivot (
  Max(answer)
  For questionID In ([1], [2], [3])
) p

http://sqlfiddle.com/#!6/8552a/8

于 2012-12-11T22:59:21.830 に答える