我正在尝试使用Pivot动态创建列,但我没有得到正在寻找的正确结果。我需要在每个问题(行)的列中显示所有可能的答案,并且课程中有多个问题。如何将每个可能的答案生成为列名,并按courseId和每行的questionId进行过滤?可能答案的数量因问题而异。这应该通过光标而不是透视来完成吗?
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX),
@courseID float(24) = 1
SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(questionID)
FROM answers
INNER JOIN questions ON questions.questionID = answers.questionID
WHERE questions.courseId = @courseID
order by 1
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
, 1, 1, '');
set @query = 'SELECT * from
(
select Q.courseId, C.courseName, Q.question, Q.questionID, A.answer
from questions Q
inner join courses C ON Q.courseId = C.courseId
inner join answers A ON A.questionID = Q.questionID
where (Q.courseId = ''' + Str(@courseID) + ''')
) x
pivot
(
max(answer)
for questionId in (' + @cols + ')
) AS p'
execute(@query)
运行上述内容时我得到了:
[1],[10],[11],[12],[13],[14],[15],[16],[2],[3],[4],[5],[6],[7],[8],[9]
生成的列是questionIds而不是'Answer 1,Answer 2 ... etc',它们没有按顺序显示。
为简洁起见,这里是数据库表中的相关列:
课程
courseId
问题
questionId question courseId
答案
AnswerId questionId answer
感谢任何帮助。
答案 0 :(得分:1)
您没有提供有关表结构的许多详细信息,但如果您希望将答案作为列Answer1
,Answer2
等,那么您需要使用{{1}创建列每个问题的答案数量与以下内容类似:
row_number()
这为每个问题的每个答案创建一个序列,然后该序列号用于创建新列名称。然后你将把你的PIVOT代码改为:
SET @cols = STUFF((SELECT ',' + QUOTENAME('Answer'+cast(seq as varchar(10)))
FROM
(
select row_number() over(partition by q.questionid
order by a.answer) seq
from answers a
INNER JOIN questions q
ON q.questionID = a.questionID
WHERE q.courseId = @courseID
) d
group by seq
order by seq
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
, 1, 1, '');