2012-12-11 57 views
1

我有以下數據的SQL Server視圖:整蠱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值忽略,正確答案放在列中。我已經看過了數據透視表的例子,但他們似乎專注於單列支點。

回答

3

爲了執行這個轉換,您將需要UNPIVOT然後PIVOT的數據。 UNPIVOT將從您的q_optionIDq_ans_text列中取值,並將其轉換爲兩列,一列爲值和列名稱。

有兩種方法你可以PIVOT這個,你可以使用靜態版本硬編碼所有的值,或者你可以使用動態sql。爲了UNPIVOT數據您需要確保數據具有相同的數據類型,因此轉換可能是必要的。

靜態PIVOT:

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 with Demo

逆透視結果:

| 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 with demo

動態PIVOT:

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 with Demo

UNION ALL /骨料與案例版本:

現在,如果你在一個沒有PIVOT然後一個系統的工作,你可以使用UNION ALLUNPIVOT和聚合函數與CASEPIVOT

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 with Demo

所有三會產生相同的結果:

| CLIENTID | SURVEYID | Q1 | Q2 | Q3 | 
--------------------------------------- 
|  1 |  1 | Yes | 18 | 19 | 
|  2 |  1 | No | 18 | 19 | 
|  3 |  2 | Yes | 15 | 13 | 
+0

+1涼爽演示 – brian

+0

感謝您的快速回復......儘管數據類型不匹配。我試着在q_optionID上進行強制轉換或轉換,但它並不真正起作用。 – TehFoobar

+0

@TehFoobar請參閱我編輯爲'UNPIVOT'數據類型必須相同的數據 – Taryn

1

沒有明確unpivot的示例。儘管如此,仍然是一種非常有用的技術!

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