将2个查询作为子查询加入到一个查询中

时间:2012-10-11 22:30:47

标签: mysql sql sql-server-2008-r2

我的第一个查询从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中建立了一个测试模式。

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

感谢您的帮助。

2 个答案:

答案 0 :(得分: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
;

答案 1 :(得分: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