mysql - 为什么 "marks < max(marks)"不起作用

标签 mysql sql

我想知道组查询的工作原理

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

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

SELECT * FROM Students
WHERE marks < MAX(marks)

但这工作正常

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

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

最佳答案

简单的回答是 SQL 就是这样设计的。较长的答案要求我们了解您的第一个查询的含义以及为什么它最终不太有意义。

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

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

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

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

关于mysql - 为什么 "marks < max(marks)"不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21949587/

相关文章:

mysql - 在mysql中选择父是否有子

SQL 8115 算术溢出错误将数字转换为数据类型数字

PHP 使用 HTML 表单更新 MySQL 表

mysql - 存在则更新,不存在则插入

mysql - 打开阅读器时如何在 VB 中打开执行查询?

java - HQL 子查询查询选择

mysql - 这个查询MYSQL怎么写

mysql - where 子句中的多个 AND OR 逻辑

java - org.hibernate.SQLQuery 输出到对象

java - 图像 Servlet 图像返回 null