【问题标题】:How to Pivot the SQL Data?如何透视 SQL 数据?
【发布时间】:2019-01-09 16:57:59
【问题描述】:

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

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   | 

【问题讨论】:

  • 您是否尝试过从答案中旋转单独的子查询/CTE 中的 cmets,然后将两个子查询/CTE 连接在一起?

标签: sql sql-server tsql pivot unpivot


【解决方案1】:

这是另一种选择,因为 SQL Server 没有简单的方法来使用枢轴运算符执行多列枢轴,所以您始终可以恢复为执行手动编码的枢轴"

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

它实际上比目前提供的其他选项更紧凑,并且可能具有更好的性能,尽管您需要自己测试该断言。

【讨论】:

    【解决方案2】:

    我将查询拆分为两个相似的枢轴,在 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
    

    【讨论】:

      【解决方案3】:

      当您取消透视数据时,您可以将 question 和 Col 列组合成一个列,以便在透视操作中使用,如下所示:

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-12
        • 2021-04-12
        相关资源
        最近更新 更多