为什么“标记< max(标记)”不起作用

时间:2014-02-22 04:17:48

标签: mysql sql

我想知道小组查询的工作情况

假设有一个表Student(id,name,marks)

现在,如果我想输出除了那些得分最高的学生以外的所有学生,为什么这个查询不起作用?

SELECT * FROM Students
WHERE marks < MAX(marks)

但这很好用

SELECT * FROM Students
WHERE marks < (SELECT MAX(marks) FROM Students)

编辑: 我已经知道了,请不要提出不同的方法来解决这个问题。 我的问题是为什么这不起作用,请仔细查看标题

1 个答案:

答案 0 :(得分:5)

简短的回答是SQL的设计方式。答案越长,我们就要看看你的第一个查询意味着什么以及为什么最终没有意义。

可以想象一个SQL,您可以将整个表的聚合与行值进行比较。但是,如果您有GROUP BY怎么办?您的MAX是针对整个桌子还是针对小组?如果您希望它针对不同的分组,或者针对整个表而不是针对组,该怎么办?

现在让我们从底层操作的角度考虑它。要实际计算行值和最大值,数据库引擎必须执行两个操作:一个用于查找最大值,另一个用于扫描表,将值与此计算的最大值进行比较。但是,在没有子查询的WHERE子句中,您只是逐行地比较列中的值。添加聚合是一种不同类型的数据,无法通过逐行查看值来收集这些数据。

另一种看待它的方法是:聚合在GROUP BY之后发生(即使GROUP BY是隐含的)。但是WHERE子句在GROUP BY之前执行。所以它无法访问聚合。

出于所有这些原因,可能还有更多原因,SQL旨在强制您在比较不同类型的值时保持明确。您必须告诉它您正在显式计算最大值,然后使用它来比较行值。这是通过子查询完成的。