2013-05-17 18 views
0

我需要使用自定義列名稱來轉換表格。請參閱下面的表格格式。SQL Server:使用自定義列名稱轉軸

當前格式

ID   question       Answer 
4482515 I would like to be informed by mail. No 
4482515 Plan to Purchase?      Over 12 months 
4482515 Test Question Text      some Answer 

我想在下面的格式顯示數據。

所需的格式

ID  question 1       Answer1 question 2   Answer 2 
4482515 I would like to be informed by mail. NO  Plan to Purchase? Over 12 months 

請注意:我不知道的問題和答案在如此列的問題1正確答案爲要動態生成的行數。

謝謝

編輯: 謝謝你的幫助,我給它一個你提供給我的動態代碼,並收到此錯誤一試。

Msg 8167, Level 16, State 1, Line 1 
The type of column "answer" conflicts with the type of other columns specified in the UNPIVOT list. 

我的表是

RID   Question Answer 
4482515 Some Question1 Some Answer1 
4482515 Some Question2 Some Answer2 
4482515 Some Question3 Some Answer3 
4484094 Some Question1 Answer1 
4484094 Some Question2 Answer2 
4484094 Some Question3 Answer3 
4484094 Some Question4 Answer4 

我打印出來的SQL,結果如下。

SELECT rid, [question1],[answer1],[question2],[answer2],[question3],[answer3],[question4],[answer4],[question5],[answer5],[question6],[answer6] 
       from 
       (
       select rid, 
        col+cast(rn as varchar(10)) col, 
        value 
       from 
       (
        select rid, question, answer, 
        row_number() over(partition by rid order by rid, question) rn 
        from #tmp_question 
       ) src 
       unpivot 
       (
        value 
        for col in (question, answer) 
       ) unpiv 
      ) d 
       pivot 
       (
        max(value) 
        for col in ([question1],[answer1],[question2],[answer2],[question3],[answer3],[question4],[answer4],[question5],[answer5],[question6],[answer6]) 
      ) p 

我原來的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 rid 
               order by rid, question) rn 
         from #tmp_question 
        ) 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 rid, ' + @cols + ' 
       from 
       (
       select rid, 
        col+cast(rn as varchar(10)) col, 
        value 
       from 
       (
        select rid, question, answer, 
        row_number() over(partition by rid order by rid, question) rn 
        from #tmp_question 
       ) src 
       unpivot 
       (
        value 
        for col in (question, answer) 
       ) unpiv 
      ) d 
       pivot 
       (
        max(value) 
        for col in (' + @cols + ') 
      ) p ' 

--print @query 
execute(@query); 

等待你的幫助!

回答

5

有幾種方法可以做到這一點。

如果你有一個已知數量的問題/答案,那麼你可以使用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 with Demo

另一個建議是同時使用UNPIVOT和PIVOT函數來獲得結果。 UNPIVOT會將您的questionanswer列轉換成多行。

爲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; 

Demo。這給出了一個結果:

|  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/answer和連續的行號值。具有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 with Demo。現在在你的情況下,你說你會有一個動態的問題/答案。如果是這樣的話,那麼你就需要使用動態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 with Demo。這些給出了結果:

|  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 | 
+0

@ user2394918如果您有問題或需要提供更多詳細信息,請修改原始帖子。請不要編輯您的詳細信息的答案。 – Taryn

+0

老兄,這不是如何編輯工作。你編輯你的問題,而不是答案,以反映你的新細節。 – Zane

+0

對不起蓋伊的我是這個論壇上的新手。請接受我的道歉。我現在編輯我的帖子,請幫我 – user2394918