我需要一个查询来获得获得Course1,Course2和Course3的学生。我可以这样查询:
SELECT k.name as firstname, k.surname as lastname, k.Email
FROM Students k
JOIN StudentCourses dn ON dn.StudentID = k.StudentID
WHERE dn.CourseID IN
(SELECT CourseID FROM Courses WHERE CourseName IN ('Course1','Course2','Course3'))
但我需要一个像这样的结果集:姓名,姓氏,电子邮件,课程1,课程2,课程3。如果学生获得该课程,则学生没有多行,一行和写课程名称。
事实上,我可以想象如何编写该查询(使用子选择),想知道更好的替代方案。
答案 0 :(得分:3)
您可以使用PIVOT
表运算符执行此操作,如下所示:
WITH CTE
AS
(
SELECT
k.name as firstname,
k.surname as lastname,
k.Email,
c.CourseName, c.CourseID
FROM Students k
JOIN StudentCourses dn ON dn.StudentID = k.StudentID
INNER JOIN Courses c ON dn.CourseID = c.CourseID
WHERE c.CourseName IN ('Course1','Course2','Course3')
)
SELECT *
FROM CTE AS c
PIVOT
(
MAX(CourseID)
FOR CourseName IN ([Course1], [Course2], [Course3])
) u;
请注意:由于您没有为每位学生在每列课程下显示其他列,因此此查询将为每个课程名称显示CourseID
值,{ {1}}如果学生没有这门课程。您应该选择显示更合适的列,例如标记:
null
这会给你:
WITH CTE
AS
(
SELECT
k.name as firstname,
k.surname as lastname,
k.Email,
c.CourseName, dn.Mark
FROM Students k
JOIN StudentCourses dn ON dn.StudentID = k.StudentID
INNER JOIN Courses c ON dn.CourseID = c.CourseID
WHERE c.CourseName IN ('Course1','Course2','Course3')
)
SELECT *
FROM CTE AS c
PIVOT
(
MAX(Mark)
FOR CourseName IN ([Course1], [Course2], [Course3])
) u;
另请注意,您应该注意在锚点查询中选择的列:
| firstname | lastname | Email | Course1 | Course2 | Course3 |
|-----------|----------|-------|---------|---------|---------|
| StudentA | test | test | 19 | 20 | 15 |
| StudentB | test | test | 16 | 17 | 20 |
| StudentC | test | test | 20 | 19 | 15 |
因为...
SELECT
k.name as firstname,
k.surname as lastname,
k.Email,
c.CourseName, dn.Mark
...
表运算符将按除列出和用于数据透视的列之外的所有列进行分组:
PIVOT
因此,在您的情况下,它将按MAX(CourseID)
FOR CourseName IN
分组。
答案 1 :(得分:1)
我认为您可以使用比您更好的查询,并使用firstname, lastname, Email
来实现您的预期结果:
MAX(CASE ...)