我需要使用自定义列名称来旋转表格。请参阅下面的表格格式。
当前格式:
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 Answer1。
谢谢
编辑: 感谢您的帮助,我试一试您为我提供的动态代码并收到此错误。
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);
等待你的帮助!
答案 0 :(得分:6)
有几种方法可以做到这一点。
如果您有一定数量的问题/答案,那么您可以使用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;
另一个建议是使用UNPIVOT和PIVOT函数来获得结果。 UNPIVOT会将您的question
和answer
列转换为多行。
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 |