SQL 2 Dimension Pivot

时间:2013-02-18 22:22:29

标签: sql sql-server sql-server-2008 tsql pivot

我想在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个答案,可随时更改,因此编码每个值并不实际。

非常感谢您的见解。

1 个答案:

答案 0 :(得分: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 with Demo

但是如果每个问题的答案数量都是未知数,那么你需要使用动态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 with Demo

两个查询的结果是:

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