1

我有一张需要使用 SQL Management Studio 转出的表。这个特定的示例存在于 SQLExpress 服务器上,但我在 2008 r2 服务器上有类似的表,我也将应用它。

此表包含调查结果(50 多个问题和数百个 GuestID)。相当直截了当,但是我在将多项选择问题和答案输入表格的方式上遇到了障碍。

我的表如下所示:

GuestID      Question                              Answer
1            How old are you?                      30
1            Do you own a car?                     Yes
1            Why do you own a car?                 Convenience
1            Why do you own a car?                 To get the girl
1            Why do you own a car?                 So I can go through the drive-thru

我想转向这个(......保持简短):

GuestID      How old..?     Do you own...?    Why do...?    Why do...?    Why do...?
1            30             Yes               Convenience   To get...     So I can go...

或者,理想情况下,结合答案转向这一点:

GuestID      How old..?     Do you own...?    Why do...?
1            30             Yes               Convenience, To get..., So I can...

我目前正在使用的声明是这样的:

declare @QuestionList as varchar(max)
select @QuestionList = 
    stuff(
    (
        select DISTINCT ',[' + RIGHT(Question,128) + ']'
        from AnnualSurveyAnswers
        where GuestId = 43
        for xml path ('')
        ),1,1,'')

declare @dynamic_PQ as varchar(max)
set @dynamic_PQ = 'select [GuestID], ' + @QuestionList + 
    'from
    (
        Select [GuestID],RIGHT([Question],128)AS Question,[Answer]
        From dbo.AnnualSurveyAnswers
    ) as S

    PIVOT

    (
        MAX([Answer])
        for Question IN (' + @QuestionList + ')
    ) as P
    '
Exec(@dynamic_PQ)

结果:

GuestID     How old...?     Do you own...?     Why do you...?
1           30              Yes                Convenience
2           35              Yes                To get the girl

我不得不添加DISTINCT@QuestionList因为我收到了关于列被多次指定的错误。说得通。我们不能有多个具有相同名称的列。但是,有了DISTINCT,它现在只显示多项选择答案之一。我还添加MAX了覆盖总需求[Answer],但也许我应该使用不同的东西?

有多项选择题,它们可能包含 1 个响应或 8 个响应。除了更改原始数据之外,还有其他选择吗?

4

1 回答 1

4

可以做一些事情来获得结果。

如果您想要单独列中的数据,那么我将包含多个答案的问题row_number()并将count()其拆分为类似于此的单独列:

declare @QuestionList as varchar(max)
declare @dynamic_PQ as varchar(max)

select @QuestionList = 
    stuff(
    (
        select DISTINCT ', ' 
          + Quotename(Question
          + case when cnt = 1 then '' else +'_'+cast(rn as varchar(10)) end)
        from
        (
          select distinct guestid,
            RIGHT(Question,128) question,
            count(*) over(partition by question) cnt,
            row_number() over(partition by question, guestid order by question) rn
          from AnnualSurveyAnswers
        ) t1
        -- where GuestId = 1
        for xml path ('')
        ),1,1,'')

set @dynamic_PQ = 'select [GuestID], ' + @QuestionList + 
    'from
    (
        Select [GuestID],
          Question
          + case when cnt = 1 then '''' else +''_''+cast(rn as varchar(10)) end Question,
          [Answer]
        from
        (
          select guestid,
            RIGHT([Question],128) AS Question,
            answer,
            count(*) over(partition by question) cnt,
            row_number() over(partition by question, guestid order by question) rn
          from dbo.AnnualSurveyAnswers
        ) src
    ) as S

    PIVOT

    (
        MAX([Answer])
        for Question IN (' + @QuestionList + ')
    ) as P
    '

Exec(@dynamic_PQ)

请参阅SQL Fiddle with Demo

这给出了结果:

| GUESTID | DO YOU OWN A CAR?_1 | HOW OLD ARE YOU?_1 | WHY DO YOU OWN A CAR?_1 | WHY DO YOU OWN A CAR?_2 |            WHY DO YOU OWN A CAR?_3 |
-----------------------------------------------------------------------------------------------------------------------------------------------
|       1 |                 Yes |                 30 |             Convenience |         To get the girl | So I can go through the drive-thru |
|       2 |                 Yes |                 38 |           Killing frogs |          To get the guy |     So I can go through the tunnel |

如果您希望将答案连接到单个列中,则可以使用:

declare @QuestionList as varchar(max)
declare @dynamic_PQ as varchar(max)

select @QuestionList = 
    stuff(
    (
        select DISTINCT ', ' 
          + Quotename(Question)
        from
        (
          select guestid,
            RIGHT(Question,128) question
          from AnnualSurveyAnswers
        ) t
        where GuestId = 1
        for xml path ('')
        ),1,1,'')

set @dynamic_PQ = 'select [GuestID], ' + @QuestionList + 
    ' from
    (
        Select [GuestID],
          Question,
          STUFF((SELECT distinct '', '' + a2.answer
                   from AnnualSurveyAnswers a2
                   where src.guestid = a2.guestid
                      and src.question = RIGHT(a2.Question,128)
                      FOR XML PATH(''''), TYPE
                      ).value(''.'', ''NVARCHAR(MAX)'') 
                  ,1,1,'''') answer
        from
        (
          select guestid,
            RIGHT([Question],128) AS Question,
            answer
          from dbo.AnnualSurveyAnswers 
        ) src
    ) as S
    PIVOT

    (
        MAX([Answer])
        for Question IN (' + @QuestionList + ')
    ) as P
    '

Exec(@dynamic_PQ)

请参阅SQL Fiddle with Demo。这给出了结果:

| GUESTID | DO YOU OWN A CAR? | HOW OLD ARE YOU? |                                             WHY DO YOU OWN A CAR? |
----------------------------------------------------------------------------------------------------------------------
|       1 |               Yes |               30 |  Convenience, So I can go through the drive-thru, To get the girl |
于 2013-03-18T20:20:52.347 回答