如何透视 SQL 数据?
Posted
技术标签:
【中文标题】如何透视 SQL 数据?【英文标题】:How to Pivot the SQL Data? 【发布时间】: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 连接在一起? 【参考方案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
【讨论】:
以上是关于如何透视 SQL 数据?的主要内容,如果未能解决你的问题,请参考以下文章