0

假设我有两张桌子:

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

你能帮我查询一下以产生结果吗?

4

2 回答 2

3

由于您有未知数量的问题,因此您需要PIVOT对此使用动态 SQL:

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)

请参阅带有演示的 SQL Fiddle

如果您有已知数量的列,那么您可以硬编码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
于 2012-10-04T21:55:34.060 回答
2

如果您不想对问题编号进行硬编码,那么您只能使用动态 SQL 来构建问题列表。

SQL Server 动态 PIVOT 查询?

对于具体问题,如果您知道他们的文本,请参阅下面的示例

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
于 2012-10-04T21:53:53.880 回答