SQL二维数据透视

SQL二维数据透视,sql,sql-server,sql-server-2008,tsql,pivot,Sql,Sql Server,Sql Server 2008,Tsql,Pivot,我想在MS SQL 2008中透视两个表,这样我就可以在一行中检索一个包含所有可用答案的调查问题 表1是“问题” 表2列出了每个问题的“答案” ID QuestionID Text 1 1 Male 2 1 Female 3 2 Yes 4 2 No 5 3 Caucasian 6 3 African/Black 7

我想在MS SQL 2008中透视两个表,这样我就可以在一行中检索一个包含所有可用答案的调查问题

表1是“问题”

表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和sub-query组合,但都没有成功

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


非常感谢您的洞察力。

您可以实现
PIVOT
功能来获得此结果

如果您知道每个
问题将有多少
答案
,那么您可以硬编码如下值:

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:

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)

两个查询的结果都是:

| 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 |

两种解决方案都非常有效!!我的问题最多有16个答案,所以第二种方法更适合我的情况。非常感谢。
| 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 |