2

我的第一个查询从 3 个表中提取学生详细信息。学生、学生地址和学生笔记。

我的查询必须列出学生的详细信息,包括 ID、姓名、地址、备注,并找到他们参加课程的最早日期。

我创建了一个聚合查询来执行此操作。

SELECT STU_Name, MIN(ENR_StartDate)
FROM Student
INNER JOIN Enrolment
ON Student.STU_Student_ID = Enrolment.ENR_Student_ID
GROUP BY STU_Name

这是我提取学生详细信息的主要查询。

SELECT STU_Name, ADD_Addr_Line_1, ADD_Addr_Line_2, ADD_Addr_Line_3, ADD_Postcode, NTE_Note, ENR_StartDate
FROM Student
INNER JOIN StudentAddress
ON Student.STU_Student_ID = StudentAddress.ADD_Student_ID
INNER JOIN StudentNote
ON Student.STU_Student_ID = StudentNote.NTE_Student_ID
INNER JOIN Enrolment
ON Student.STU_Student_ID = Enrolment.ENR_Student_ID

我想链接这些查询,以便结果集告诉我该行中每个学生的最早开始日期。

学生期望的输出

row0: student1id, student1name, student1address, student1note1, student1startdate

row1: student1id, student1name, student1address, student1note2, student1startdate

这将允许一个学生有多个笔记,但是对于一个学生来说,开始的开始总是被计算为相同的。

我在 sql fiddle 中构建了一个测试模式。

http://sqlfiddle.com/#!2/cecea/4

谢谢你的帮助。

4

2 回答 2

1

请注意,您没有注意到其中一名学生。这已通过外部连接得到纠正。

在另一种情况下,一个学生有 2 个笔记。所以那个学生在结果中有两行。

要解决这个问题,您需要选择一个特定的注释(第一个、最后一个等)。您可以使用与查找每个学生的第一个注册记录相同的逻辑来执行此操作。

调整以处理学生在同一入学日期可能有不止一排的情况。这种方法可以用来打破大多数这些类型的关系。请注意,窗口函数通常是更好的方法,但 MySQL 不支持它们。

SELECT STU_Name
     , ADD_Addr_Line_1
     , ADD_Addr_Line_2
     , ADD_Addr_Line_3
     , ADD_Postcode
     , NTE_Note
     , Enrolment.ENR_StartDate
     , Enrolment.ENR_ID
     , Student.STU_Student_ID
     , StudentAddress.ADD_ID
     , StudentNote.NTE_ID
  FROM Student
  JOIN StudentAddress
    ON Student.STU_Student_ID = StudentAddress.ADD_Student_ID
  LEFT JOIN StudentNote
    ON Student.STU_Student_ID = StudentNote.NTE_Student_ID
  JOIN Enrolment
    ON Student.STU_Student_ID = Enrolment.ENR_Student_ID
  LEFT JOIN Enrolment AS e2
    ON Enrolment.ENR_Student_ID = e2.ENR_Student_ID
   AND (Enrolment.ENR_StartDate, Enrolment.ENR_ID) > (e2.ENR_StartDate, e2.ENR_ID)
 WHERE e2.ENR_StartDate IS NULL
;
于 2012-10-11T22:57:53.327 回答
0

您应该为所有列添加表别名以指定它们的来源。

SELECT STU_Name, ADD_Addr_Line_1, ADD_Addr_Line_2, ADD_Addr_Line_3, ADD_Postcode, NTE_Note, ENR_StartDate,
    G.EarliestStartDate
FROM Student
JOIN StudentAddress
        ON Student.STU_Student_ID = StudentAddress.ADD_Student_ID
JOIN StudentNote
        ON Student.STU_Student_ID = StudentNote.NTE_Student_ID
JOIN Enrolment
        ON Student.STU_Student_ID = Enrolment.ENR_Student_ID
JOIN (
  SELECT Student.STU_Student_ID, MIN(ENR_StartDate) EarliestStartDate
  FROM Student
  INNER JOIN Enrolment
  ON Student.STU_Student_ID = Enrolment.ENR_Student_ID
  GROUP BY STU_Name
) G on G.STU_Student_ID = Student.STU_Student_ID
于 2012-10-11T22:36:07.887 回答