我们假设我有两张桌子:
Question (Id, Text)
Answer (Value, QuestionId, Guid)
专栏Guid
将来自同一个人的答案分组。
我需要一个查询来生成这样的结果:
'Question 1' | 'Question 2'
4 | 3
1 | NULL
NULL | 5
2 | 6
9 | NULL
问题文本转换为列标题,答案值按行排列。答案按Guid
分组,因此一行中有一个人的答案。如果某人没有回答特定问题,则返回NULL。
问题的数量可能会有所不同。
用于生成样本结果的数据:
Question
Id | Text
1 | Question 1
2 | Question 2
Answer
Value | QuestionId | Guid
4 | 1 | AAA
3 | 2 | AAA
1 | 1 | BBB
5 | 2 | CCC
2 | 1 | DDD
6 | 2 | DDD
9 | 1 | EEE
你能帮我解决一下产生结果吗?
答案 0 :(得分:3)
由于您的问题数量未知,因此tou需要使用动态SQL PIVOT
:
DECLARE @colsFinal AS NVARCHAR(MAX),
@colsPivot AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @colsFinal = STUFF((SELECT distinct ','
+ QUOTENAME(Id)
+ ' as Question_'+ cast(Id as varchar(10))
from question
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
select @colsPivot = STUFF((SELECT distinct ','
+ QUOTENAME(Id)
from question
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT ' + @colsFinal + ' from
(
select questionid, value, guid
from question q
left join value v
on q.id = v.questionid
) x
pivot
(
min(value)
for questionid in (' + @colsPivot + ')
) p '
execute(@query)
如果您有已知数量的列,那么您可以对PIVOT
的值进行硬编码(请参阅SQL Fiddle With Demo):
select [1] as Question1, [2] as Question2
from
(
select questionid, value, guid
from question q
left join value v
on q.id = v.questionid
) x
pivot
(
max(value)
for questionid in ([1], [2])
) p
或者你可以使用CASE
的聚合函数(参见SQL Fiddle With Demo):
select max(case when q.id = 1 then v.value end) Question1,
max(case when q.id = 2 then v.value end) Question2
from question q
left join value v
on q.id = v.questionid
group by guid
答案 1 :(得分:2)
如果您不想对问题编号进行硬编码,那么您只能使用动态SQL来构建问题列表。
SQL Server dynamic PIVOT query?
对于具体问题,如果您知道他们的文本,请参阅下面的示例
create table Question(id int, text varchar(100));
insert Question select 1, 'Question 1'
union all select 2, 'The 2nd';
create table Answer(
value int,
questionid int,
guid varchar(10));
insert Answer select
4 , 1 , 'AAA' union all select
3 , 2 , 'AAA' union all select
1 , 1 , 'BBB' union all select
5 , 2 , 'CCC' union all select
2 , 1 , 'DDD' union all select
6 , 2 , 'DDD' union all select
9 , 1 , 'EEE';
GO
select guid, [Question 1], [The 2nd]
from (
select guid, text, value
from Answer A
join Question Q on A.questionid=q.id) p
pivot (max(value) for text in ([Question 1], [The 2nd])) v