9

假设 value 是一个 int 并且以下查询是有效的:

SELECT blah
FROM table
WHERE attribute = value

尽管 MAX(expression) 返回 int,但以下内容无效:

SELECT blah
FROM table
WHERE attribute = MAX(expression)

当然,使用子查询可以达到预期的效果,但我的问题是为什么 SQL 是这样设计的——有什么理由不允许这种事情吗?来自编程语言的学生总是可以通过返回该类型的函数调用来替换数据类型,发现这个问题令人困惑。有没有可以给他们的解释,而不仅仅是说“就是这样”?

4

5 回答 5

16

这只是因为查询的操作顺序。

  1. FROM 子句
  2. WHERE 子句
  3. GROUP BY 子句
  4. HAVING 子句
  5. 选择子句
  6. ORDER BY 子句

WHERE只过滤返回的行FROM。像这样的聚合函数MAX()不能返回结果,因为它甚至还没有应用于任何东西。

这也是为什么不能在SELECT子句中使用子句中定义的WHERE别名,但可以使用子句中定义的别名的原因FROM

于 2013-09-18T16:23:05.240 回答
5

where 子句检查每一行以查看它是否与指定的条件匹配。

最大值从行集中计算单个值。如果将 max 或任何其他聚合函数放入 where 子句中,SQL 服务器如何确定 max 函数可以使用哪些行,直到 where 子句完成过滤?

这处理 SQL Server 处理命令的顺序。它在 GROUP BY 或任何聚合之前运行 WHERE 子句。由于 where 子句首先运行,因此 SQL Server 在处理 where 之前无法判断行是否将包含在聚合中。这就是 HAVING 子句的用途。HAVING 在 GROUP BY 和 WHERE 之后运行,并且可以包含 MAX,因为您已经过滤掉了不想使用的行。有关 SQL 命令运行顺序的详细说明,请参阅http://www.bennadel.com/blog/70-SQL-Query-Order-of-Operations.htm

于 2013-09-18T16:28:01.117 回答
4

也许这项工作

SELECT blah
FROM table
WHERE attribute = (SELECT MAX(expresion) FROM table1)
于 2017-03-16T18:55:48.040 回答
2

WHERE子句专门设计用于针对原始数据(表的各个行)测试条件。但是,MAX它是对多行数据的聚合函数。基本上,没有子选择,WHERE 子句对表中除了当前行之外的任何行一无所知。那么,当您甚至不知道这些行是什么时,如何确定一大堆行的最大值呢?

是的,这有点简化,尤其是在处理连接时,但同样的原则也适用。WHERE总是一行一行的,所以这就是它真正知道的一切。

即使您有一个GROUP BY子句,该WHERE子句在分组之前仍然一次只处理原始数据中的一行。它不知道任何其他行中列的值,因此它无法知道哪一行具有最大值。

于 2013-09-18T16:39:39.897 回答
0

假设这是 MS SQL Server,以下将起作用。

SELECT TOP 1 blah
FROM table
ORDER BY expression DESC
于 2013-09-18T16:24:51.730 回答