1

我想在 MS SQL 2008 中对 2 个表进行透视,以便在一行中检索一个包含所有可用答案的调查问题。

表1是“问题”

ID   Text
1    What is your gender
2    Are you married
3    What is your Ethnicity

表 2 为每个问题提供“答案”

ID   QuestionID   Text
1    1            Male
2    1            Female
3    2            Yes
4    2            No
5    3            Caucasian
6    3            African/Black
7    3            Hispanic
8    3            Asian
etc.

我希望我的查询结果如下所示:

QuestionID  QuestionText             Ans1       Ans2            Ans3      Ans4
1           What is your gender      Male       Female          Null      Null
2           Are you married          Yes        No              Null      Null
3           What is your Ethnicity   Caucasian  African/Black   Hispanic  Asian

我尝试了 10 种不同的 Pivot、CTE 和子查询组合,但都没有成功。

我应该提到没有“答案序列”列(还)。真正的数据库有 200 多个问题和 700 个答案,随时可能发生变化,因此对每个值进行编码是不切实际的。

感谢您的洞察力。

4

1 回答 1

3

您可以实现该PIVOT函数来获得此结果。

answers如果您知道每个 将有多少question,那么您可以对类似于以下的值进行硬编码:

select *
from
(
  select q.id,
    q.text question,
    a.text answer,
    'Answer_'+cast(row_number() over(partition by q.id 
                                      order by a.id) as varchar(10)) col
  from questions q
  left join answers a
    on q.id = a.questionid
) src
pivot
(
  max(answer)
  for col in (Answer_1, Answer_2,
             Answer_3, Answer_4)
) piv
order by id;

请参阅带有演示的 SQL Fiddle

但是,如果每个问题的答案数量未知,则需要使用动态 sql:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME('Answer_'+cast(row_number() over(partition by q.id 
                                      order by a.id) as varchar(10))) 
                    from questions q
                    left join answers a
                      on q.id = a.questionid
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT id, question, ' + @cols + ' from 
             (
                select q.id,
                  q.text question,
                  a.text answer,
                  ''Answer_''+cast(row_number() over(partition by q.id 
                                                    order by a.id) as varchar(10)) col
                from questions q
                left join answers a
                  on q.id = a.questionid
            ) x
            pivot 
            (
                max(answer)
                for col in (' + @cols + ')
            ) p 
            order by id'

execute(@query)

请参阅带有演示的 SQL Fiddle

两个查询的结果是:

| ID |               QUESTION |  ANSWER_1 |      ANSWER_2 | ANSWER_3 | ANSWER_4 |
---------------------------------------------------------------------------------
|  1 |    What is your gender |      Male |        Female |   (null) |   (null) |
|  2 |        Are you married |       Yes |            No |   (null) |   (null) |
|  3 | What is your Ethnicity | Caucasian | African/Black | Hispanic |    Asian |
于 2013-02-18T22:39:55.593 回答