SQL-在WHERE子句中使用MAX

SQL-在WHERE子句中使用MAX,sql,max,where,Sql,Max,Where,假设值为int,且以下查询有效: SELECT blah FROM table WHERE attribute = value 虽然MAX(expression)返回int,但以下内容无效: SELECT blah FROM table WHERE attribute = MAX(expression) 当然,使用子查询可以达到预期的效果,但我的问题是为什么SQL是这样设计的——有什么原因不允许这样做吗?来自编程语言的学生总是可以用返回数据类型的函数调用替换数据类型,他们发现这个问题令人困惑

假设值为int,且以下查询有效:

SELECT blah
FROM table
WHERE attribute = value
虽然MAX(expression)返回int,但以下内容无效:

SELECT blah
FROM table
WHERE attribute = MAX(expression)

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

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

  • FROM子句
  • WHERE子句
  • 分组依据子句
  • 有从句
  • SELECT子句
  • 按条款订货
  • 其中
    只过滤
    返回的行。像
    MAX()
    这样的聚合函数不能返回结果,因为它甚至没有应用于任何对象


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

    假设这是MS SQL Server,下面的操作就可以了

    SELECT TOP 1 blah
    FROM table
    ORDER BY expression DESC
    

    where子句检查每一行,看它是否符合指定的条件

    max从行集中计算单个值。如果将max或任何其他聚合函数放入where子句中,在where子句完成筛选之前,SQL server如何确定max函数可以使用哪些行


    这涉及SQL Server处理命令的顺序。它在GROUP BY或任何集合之前运行WHERE子句。由于where子句首先运行,SQL Server在处理where之前无法判断某一行是否包含在聚合中。这就是HAVING子句的作用。由于已经过滤掉了不想使用的行,因此在GROUP BY和WHERE and之后运行可以包括MAX。有关SQL命令运行顺序的详细说明,请参见。

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

    是的,这有点简化,特别是在处理连接时,但同样的原则也适用<代码>其中始终是一行一行,所以它真正知道的就是这些

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

    也许这是可行的

    SELECT blah
    FROM table
    WHERE attribute = (SELECT MAX(expresion) FROM table1)
    

    我能想到的最好方法是:
    max()
    是一个聚合函数,它使它不同于标量函数(可以在
    where
    子句中使用)。由于聚合需要对“行”进行操作,因此不能将其应用于(标量)表达式。在
    max(expression)
    max()中,您考虑的是来自哪个集合的哪种表达式?函数作用于一组数据,如果没有一组数据,函数将如何运行?来自编程语言[…]的学生发现这个问题令人困惑,可能是因为SQL是一种查询语言而不是编程语言。正则表达式和xslt需要相同类型的心智模型更改,并导致类似的挫折。
    TOP
    仅在MS products中实现。尽管此答案再现了OP预期的结果,但它不是问题的答案。OP中没有指定他使用MS产品的地方,因此
    TOP
    只是一个“部分”解决方案,您应该在拥有:-)之后添加“窗口功能”)