我有一个包含以下数据的SQL Server视图:
ID clientID surveyID questionID q_optionID q_ans_text
-----------------------------------------------------------------
1 1 1 1 NULL Yes
2 1 1 2 18 NULL
3 1 1 3 19 NULL
4 2 1 1 NULL No
5 2 1 2 18 NULL
6 2 1 3 19 NULL
7 3 2 1 NULL Yes
8 3 2 2 15 NULL
9 3 2 3 13 NULL
我希望结果是这样的:
ClientID SurveyID Q1 Q2 Q3
------------------------------------
1 1 Yes 18 19
2 1 No 18 19
3 2 Yes 15 13
忽略条件NULL
值并在列中放置正确答案。我看过Pivot表的例子,但他们似乎专注于单列支点。
答案 0 :(得分:3)
要执行此转换,您需要UNPIVOT
,然后PIVOT
数据。 UNPIVOT
将获取q_optionID
和q_ans_text
列中的值,并将其转换为两列,其中包含值和列名称。
有两种方法可以PIVOT
这个,您可以使用静态版本对所有值进行硬编码,也可以使用动态sql。为了UNPIVOT
数据,您需要确保数据具有相同的数据类型,因此可能需要进行转换。
静态PIVOT:
select clientid, surveyid,
questionid,
value,
col
from
(
select clientid, surveyid, questionid,
cast(q_optionID as varchar(4)) q_optionID,
q_ans_text
from yourtable
) s
unpivot
(
value
for col in (q_optionID, q_ans_text)
) un
取消透露结果:
| CLIENTID | SURVEYID | QUESTIONID | VALUE | COL |
---------------------------------------------------------
| 1 | 1 | 1 | Yes | q_ans_text |
| 1 | 1 | 2 | 18 | q_optionID |
| 1 | 1 | 3 | 19 | q_optionID |
| 2 | 1 | 1 | No | q_ans_text |
| 2 | 1 | 2 | 18 | q_optionID |
| 2 | 1 | 3 | 19 | q_optionID |
| 3 | 2 | 1 | Yes | q_ans_text |
| 3 | 2 | 2 | 15 | q_optionID |
| 3 | 2 | 3 | 13 | q_optionID |
然后,您将PIVOT
应用于结果以获得最终产品。
select *
from
(
select clientid, surveyid,
'Q'+cast(questionid as varchar(10)) question,
value
from
(
select clientid, surveyid, questionid,
cast(q_optionID as varchar(4)) q_optionID,
q_ans_text
from yourtable
) s
unpivot
(
value
for col in (q_optionID, q_ans_text)
) un
) src
pivot
(
max(value)
for question in (Q1, Q2, Q3)
) piv
动态PIVOT:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME('Q'+cast(questionid as varchar(10)))
from yourtable
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT clientid, surveyid,' + @cols + ' from
(
select clientid, surveyid,
''Q''+cast(questionid as varchar(10)) question,
value
from
(
select clientid, surveyid, questionid,
cast(q_optionID as varchar(4)) q_optionID,
q_ans_text
from yourtable
) s
unpivot
(
value
for col in (q_optionID, q_ans_text)
) un
) x
pivot
(
max(value)
for question in (' + @cols + ')
) p '
execute(@query)
UNION ALL /与案例版本汇总:
现在,如果您在没有PIVOT
的系统中工作,那么您可以使用UNION ALL
到UNPIVOT
以及使用CASE
到{的汇总函数{1}}:
PIVOT
这三个都会产生相同的结果:
select clientid, surveyid,
max(case when questionid = 1 then value end) Q1,
max(case when questionid = 2 then value end) Q2,
max(case when questionid = 3 then value end) Q3
from
(
select clientid, surveyid, questionid, cast(q_optionID as varchar(10)) value, 'q_optionID' col
from yourtable
union all
select clientid, surveyid, questionid, q_ans_text value, 'q_ans_text' col
from yourtable
) unpiv
group by clientid, surveyid
答案 1 :(得分:1)
没有显式unpivot的示例。尽管如此,仍然是一个非常有用的技术!
Select
clientID,
SurveyID,
[1] as Q1,
[2] as Q2,
[3] as Q3
From (
Select
clientID,
surveyID,
questionID,
IsNull(Cast(q_optionID as varchar(10)), q_ans_text) answer
From
Answers
) a
Pivot (
Max(answer)
For questionID In ([1], [2], [3])
) p
答案 2 :(得分:0)
select
clientid, surveyid,
max(case when questionid = 1 then coalesce(q_ans_text, cast(q_optionID as char)) else null end) as Q1,
max(case when questionid = 2 then coalesce(q_ans_text, cast(q_optionID as char)) else null end) as Q2,
max(case when questionid = 3 then coalesce(q_ans_text, cast(q_optionID as char)) else null end) as Q3
from yourtable
group by clientid, surveyid