我发现了一个类似的问题:What is the order of execution for this SQL statement。接受的答案指定FROM在任何其他条款之前执行。
SELECT StudentName, Students.StudentID, Cnt
FROM (
SELECT Students.StudentID, count(StudentCourses.CourselD) as [Cnt]
FROM Students LEFT JOIN StudentCourses
ON Students.StudentID = StudentCourses.StudentID GROUP BY Students.StudentID
) T INNER JOIN Students on T.StudentID = Students.StudentID
在这种情况下count()如何工作?
我很困惑,因为它似乎没有遵循我的逻辑。假设首先执行嵌套FROM中的LEFT JOIN(如果这是错误的,请告诉我),我们将为每个学生至少有一行作为中间输出,如果学生没有参加任何课程,可能值为null 。如果count()应用于该输出,则这些学生将因为空值行而计数1,这在实际结果中不会发生。任何人都可以解释这个查询是如何在幕后执行的吗?
提前致谢
答案 0 :(得分:0)
您的问题不符合执行顺序。我认为这更多是因为
COUNT(StudentCourses.CourselD)
只计算非空结果。
将此作为:
SELECT Students.StudentID, count(*) as [Cnt]
FROM Students LEFT JOIN StudentCourses
ON Students.StudentID = StudentCourses.StudentID GROUP BY Students.StudentID
会返回所有行的计数,而不仅仅是那些课程ID不为空的计数。
答案 1 :(得分:0)
COUNT()
位于子查询中,外部查询中不。您只能在外部查询中选择count()返回的值。
子查询中Cnt列的值将是一个大于或等于0的整数(因为COUNT(NULL)
返回0,并且并非所有学生都在StudentCourses表中有行,我相信你会在该列中有零)。子查询为每个学生返回一行,COUNT()
值为0或更多。
此外,正如Paolo在评论中提到的那样 - 逻辑顺序!=执行顺序,所以不要假设在什么之前执行了什么。数据库引擎有多种机制来优化查询执行,所以你应该更喜欢阅读文档来假设它是如何工作的。