我有几张桌子:
Exams
UserExams
UserExamQuestions
UserExamAnswers
Users
ExamQuestions
ExamQuestionAnswers
这是我开发的选择
select ue.DateStarted as 'Date Started', u.LastName as 'Lastname',
u.FirstName as 'Firstname', eq.Text as 'Question', eqa.Text as 'Answer',
eqa.IsCorrect as 'Correct' from Exams e
join UserExams ue on ue.ExamId = e.Id
join UserExamQuestions ueq on ueq.UserExamId = ue.Id
join UserExamAnswers uea on uea.UserExamQuestionId = ueq.Id
join Users u on u.Id = ue.UserId
join ExamQuestions eq on eq.Id = ueq.ExamQuestionId
join ExamQuestionAnswers eqa on eqa.Id = uea.ExamQuestionAnswerId
where e.Id = 10 and uea.IsSelected = 1
order by u.LastName, u.FirstName
但不幸的是,它以不受欢迎的方式返回数据。返回的行看起来像这样
Date Started Lastname Firstname Question Answer Correct
2012-02-26 13:29:50.770 Somename Somefirstname Some question text? Some answer 0
2012-02-26 13:30:20.000 Othername Otherfirstname Some question text? Some answer 0
2012-02-26 15:10:10.212 Fifth Fifthname Some question text? Other answer 1
当然上面的例子是针对三个用户,他们用一些答案回答了一个问题。选定的数据很好,但我需要它是这样的:
Lastname Firstname [Some question text?] Correct
Somename Somefirstname Some answer 0
Othername Otherfirstname Some answer 0
Fifth Fifthname Other answer 1
有可能吗?它不一定要快。在代码背后做这件事会很痛苦......我试图转向,但首先 - 我认为我没有正确理解它,其次我不想聚合数据。
感谢您的帮助。
答案 0 :(得分:2)
确定。所以我确实看到你的答案,我有一个建议给你。当你说你要用枢轴做到这一点时,你真正纠正的地方。
首先,我为了测试目的简化了数据。测试数据如下:
CREATE TABLE Table1
(
Lastname VARCHAR(100),
Firstname VARCHAR(100),
Answer VARCHAR(100),
Question VARCHAR(100),
Correct BIT
)
INSERT INTO Table1
VALUES
('Somename','Somefirstname','Some answer','Some question text?',0),
('Somename','Somefirstname','Answer to second question','Second question in same column?',1),
('Othername','Otherfirstname','Some answer','Some question text?',0),
('Othername','Otherfirstname','Wrong answer to second question','Second question in same column?',0),
('Fifth','Fifthname','Other answer','Some question text?',1),
('Fifth','Fifthname','Wrong answer to second question','Second question in same column?',0)
您需要获取要转动的唯一列。像这样:
DECLARE @Questions VARCHAR(MAX)
;WITH CTE
AS
(
SELECT
ROW_NUMBER() OVER(PARTITION BY Question ORDER BY Question) AS RowNbr,
ROW_NUMBER() OVER(ORDER BY Question) AS OrderBy,
Table1.Question
FROM
Table1
), CTE2
AS
(
SELECT
CTE.OrderBy AS OrderBy,
1 AS SecondOrder,
CTE.Question
FROM
CTE
WHERE
CTE.RowNbr=1
UNION ALL
SELECT
CTE.OrderBy AS OrderBy,
2 AS SecondOrder,
'Is '+CTE.Question
FROM
CTE
WHERE
CTE.RowNbr=1
)
SELECT
@Questions = COALESCE(@Questions + ','+QUOTENAME(Question),
QUOTENAME(Question))
FROM
CTE2
ORDER BY
CTE2.OrderBy,
CTE2.SecondOrder
第一个ROW_NUMBER() OVER(PARTITION BY Question ORDER BY Question)
是获取唯一列。稍后我将使用where
语句。
第二个ROW_NUMBER() OVER(ORDER BY Question)
是订购问题
SecondOrder
以便您在“是”问题之前订购问题
UNION ALL
是UNION ALL
问题和“是”问题
@Questions = COALESCE(@Questions + ','+QUOTENAME(Question),
..将列合并为一个varchar
然后我们需要为pivot创建一些动态sql,最后执行它。像这样:
DECLARE @query NVARCHAR(4000)=
N';WITH CTE
AS
(
SELECT
Table1.Lastname,
Table1.Firstname,
Table1.Answer,
Table1.Question
FROM
Table1
UNION ALL
SELECT
Table1.Lastname,
Table1.Firstname,
CAST(Table1.Correct AS VARCHAR(10)) AS Answer,
''Is ''+Table1.Question AS Question
FROM
Table1
)
SELECT
*
FROM
(
SELECT
CTE.Lastname,
CTE.Firstname,
CTE.Answer,
CTE.Question
FROM
CTE
) AS p
PIVOT
(
MAX(Answer)
FOR Question IN ('+@Questions+')
) AS pvt'
EXECUTE(@query)
然后我们需要UNION ALL
带有“是”问题的问题
Correct
列已转换为VARCHAR
,因为UNION ALL
和数据透视不允许使用不同的数据类型
我们将使用MAX
聚合来获得我们需要的答案。这是因为枢轴要求我们使用聚合。
FOR Question IN ('+@Questions+')
是我们在上面的查询中汇总的列。
您可以查看结果和示例数据here
我希望这会对你有所帮助
答案 1 :(得分:2)
Arion - 您的脚本会将所有问题提取到一列中,如下所示:
Lastname Firstname [Some question text?,Second question in same column?] Correct
Somename Somefirstname Some answer 0
Somename Somefirstname Answer to second question 1
Othername Otherfirstname Some answer 0
Othername Otherfirstname Wrong answer to second question 0
Fifth Fifthname Other answer 1
Fifth Fifthname Wrong answer to second question 0
我需要的是这样的:
Lastname Firstname [Some question text?] [Is Some question answer correct] [Second question in same column?] [Is Second question in same column answer correct]
Somename Somefirstname Some answer 0 Answer to second question 1
Othername Otherfirstname Some answer 0 Wrong answer to second question 0
Fifth Fifthname Other answer 1 Wrong answer to second question 0