如何透视SQL数据?

时间:2019-01-09 16:57:59

标签: sql sql-server tsql pivot unpivot

我有一个与调查有关的数据集,我必须在它们上创建一个视图。数据集的格式为:

surveyID    RID    Question   Answer     Comment
-----------------------------------------------------------------
17     |   123  |   Q1     |   0      |
17     |   123  |   Q2     |          |   The salesperson and manager was very considerate and I will be coming back for my next car!
17     |   123  |   Q3     |   5      |   Very bad behavior

所需结果为

surveyID |   RID  |  Q1  |  Q1_c |  Q2  |  Q2_c  |  Q3  |  Q3_c 
-----------------------------------------------------------------
17       |   123  |  0   |       |      | The... |  5   | Very...

问题和问题注释应在上面的标题行中:

我试图获得结果,但只有在我将1列(即“答案”列)旋转但如何同时使“答案”和“注释”列同时旋转时,我才能成功?

这是我完成的查询

select rid, surveyid, --comment,    
    Q1,Q2,Q3
from
(
  select rid, surveyid, question, --comment,    
    value
  from
  (
    select rid, surveyid, question, -- comment,
      answer      
    from #temp
  ) s
  unpivot
  (
    value
    for col in (answer)
  ) un
) src
pivot
(
  max(value)
  for question in (Q1, Q2, Q3)
) piv

结果是:

surveyID |   RID  |  Q1  |  Q2  |  Q3  |  
-----------------------------------------------------------------
17       |   123  |  0   |      |  5   | 

3 个答案:

答案 0 :(得分:3)

Here's another alternative, since SQL Server doesn't have an easy way to do a multi-column pivot with the pivot operator, you can always revert to performing a hand coded pivot"

select surveyID, rid
     , max(case question when 'Q1' then answer end) q1
     , max(case question when 'Q1' then comment end) q1_c
     , max(case question when 'Q2' then answer end) q2
     , max(case question when 'Q2' then comment end) q2_c
     , max(case question when 'Q3' then answer end) q3
     , max(case question when 'Q3' then comment end) q3_c
  from #temp
 group by surveyID, rid

It's actually more compact than the other options presented so far and possibly has better performance, though you'd need to test that assertion for yourself.

答案 1 :(得分:1)

我将查询分为两个类似的枢轴,将数据旋转到CTE中,然后将CTE连接在一起。

;WITH QnA AS
(
    SELECT
        RID
        ,surveyID
        ,Q1
        ,Q2
        ,Q3
    FROM
    ( SELECT RID, surveyID, Question, Answer FROM #temp ) src
    PIVOT
    (
        MAX(Answer)
        FOR Question IN ( Q1
            ,Q2
            ,Q3
        )
    ) piv
)
,QnAComments AS
(
    SELECT
        RID
        ,surveyID
        ,Q1_c = Q1
        ,Q2_c = Q2
        ,Q3_c = Q3
    FROM
    ( SELECT RID, surveyID, Question, Comment FROM #temp ) src
    PIVOT
    (
        MAX(Comment)
        FOR Question IN ( Q1
            ,Q2
            ,Q3
        )
    ) piv
)
SELECT
    QnA.surveyID
    ,QnA.RID
    ,Q1
    ,Q1_c
    ,Q2
    ,Q2_c
    ,Q3
    ,Q3_c
FROM QnA
INNER JOIN QnAComments ON QnAComments.RID = QnA.RID
                           AND QnAComments.surveyID = QnA.surveyID

答案 2 :(得分:1)

取消数据透视时,可以将问题列和列列合并为一个列,以用于数据透视操作,如下所示:

select * from (
  select surveyid, rid, question+'_'+col QC, value from (
    select rid, surveyid, question, Comment,
      cast(answer as varchar(91)) Answer
    from #temp
  ) s
  unpivot
  (
    value
    for col in (Answer, Comment)
  ) un
  ) src
 pivot
(
  max(value)
  for QC in (Q1_Answer, Q1_Comment, Q2_Answer, Q2_Comment, Q3_Answer, Q3_Comment)
) piv

您可以通过一些小的调整来获得所需的列标题:

select * from (
  select surveyid, rid, question+case col when 'comment' then '_c' end QC, value from (
    select rid, surveyid, question, Comment,
      cast(answer as varchar(91)) Answer
    from #temp
  ) s
  unpivot
  (
    value
    for col in (Answer, Comment)
  ) un
  ) src
 pivot
(
  max(value)
  for QC in (Q1, Q1_C, Q2, Q2_C, Q3, Q3_C)
) piv