2013-05-17 2 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 

참고 : 나는 ANSWER1가 동적으로 생성해야하는 열의 question1 있도록 행의 질문과 답변의 수에 대해 알고하지 않습니다.

당신에게

편집 감사합니다 는 당신의 도움을 주셔서 감사합니다, 나는 그것을 동적 당신이 나에게 제공 코드와이 오류를 얻기위한 시도를 제공합니다.

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. 

내 표는 제가 SQL을 인쇄

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 

이며, 그 결과는 다음과 같습니다.

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

이렇게 할 수있는 방법이 몇 가지 있습니다.

질문/답변 알려진 번호를 가지고 있다면 당신은 집계 함수와 CASE 표현식과 함께 row_number()을 사용할 수 있습니다 또 다른 제안은 모두를 사용하는 것입니다

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