我有一个表需要使用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个响应。除了改变原始数据之外还有其他选择吗?
答案 0 :(得分: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)
这给出了结果:
| 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 |