Sql 使学生的课程位于同一行的查询

Sql 使学生的课程位于同一行的查询,sql,sql-server,tsql,pivot,Sql,Sql Server,Tsql,Pivot,我需要一个查询,将得到谁得到课程1,课程2和课程3的学生。我可以这样查询: 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','C

我需要一个查询,将得到谁得到课程1,课程2和课程3的学生。我可以这样查询:

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。一个学生不能有多行,一行写下课程名称,如果学生得到了该课程


事实上,我可以想象如何编写该查询(使用subselect),想知道更好的替代方法。

您可以使用
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;
SELECT k.name as firstname, k.surname as lastname, k.Email,
    MAX(CASE WHEN c.CourseName = 'Course1' THEN 'Yes' ELSE 'No' END) As Course1,
    MAX(CASE WHEN c.CourseName = 'Course2' THEN 'Yes' ELSE 'No' END) As Course2,
    MAX(CASE WHEN c.CourseName = 'Course3' THEN 'Yes' ELSE 'No' END) As Course3
FROM Students k
JOIN StudentCourses dn ON dn.StudentID = k.StudentID
JOIN Courses c ON c.CourseID = dn.CourseID AND c.CourseName Like 'Course[1-3]'
GROUP BY k.name, k.surname, k.Email;

请注意,由于您没有其他列显示在每个学生的每一列课程下,如果学生没有此课程,此查询将显示每个课程名称的
CourseID
值,
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
table操作符将按您列出并用于透视的列以外的所有列进行分组:

MAX(CourseID)
  FOR CourseName IN

因此,在您的情况下,它将按
firstname、lastname、Email

进行分组。我认为您可以使用比您的查询更好的查询,并使用
MAX(case…
来实现您的预期结果,如下所示:

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;
SELECT k.name as firstname, k.surname as lastname, k.Email,
    MAX(CASE WHEN c.CourseName = 'Course1' THEN 'Yes' ELSE 'No' END) As Course1,
    MAX(CASE WHEN c.CourseName = 'Course2' THEN 'Yes' ELSE 'No' END) As Course2,
    MAX(CASE WHEN c.CourseName = 'Course3' THEN 'Yes' ELSE 'No' END) As Course3
FROM Students k
JOIN StudentCourses dn ON dn.StudentID = k.StudentID
JOIN Courses c ON c.CourseID = dn.CourseID AND c.CourseName Like 'Course[1-3]'
GROUP BY k.name, k.surname, k.Email;

使用PIVOT/UNPIVOT运算符,您可以仅使用一个学生和课程列拉动行,并使用该运算符转换数据或抛出一些示例数据(无图像)a并输出所需结果假设您只有3门课程我已硬编码案例,否则需要更改查询
选择k.name作为firstname,k.姓氏作为lastname,k.电子邮件,当dn.CourseName='Course1'然后'Course1'其他'-'作为Course1结束时,当dn.CourseName='Course2'然后'Course2'其他'-'作为Course2结束时,当dn.CourseName='Course3'然后'Course3'其他'-'作为Course3结束时,从Students k加入StudentCourses dn ON dn.StudentID=k.StudentID加入CourseId作为ci ON dn.CourseId=ci.id
您希望在coursename下为每行显示什么?我可以写课程名称或是/否。无所谓。