SQL MAX()如何工作?

时间:2015-03-26 13:21:15

标签: mysql max

SQL MAX应该很容易理解,但为什么我的查询不能按预期工作?

这是架构和数据

CREATE TABLE orders(
    id INT,
    name TEXT,
    quantity INT, 
    PRIMARY KEY (id)
);
INSERT INTO orders VALUES 
    (1, 'abc', 10), 
    (2, 'def', 3), 
    (3, 'abc', 2),
    (4, 'ghi', 4),
    (5, 'ghi', 7),
    (6, 'ghi', 13);

这是查询

select t.name, max(t.avgq) from (
    select name, avg(quantity) as avgq 
    from orders group by name
) as t;

我从mysql和sqlfiddle得到的结果都是这样的

name    max(t.avgq)
-----+-------------
abc        8

实际应该在哪里

name    max(t.avgq)
-----+--------------
ghi        8

为什么?

4 个答案:

答案 0 :(得分:4)

MAX()将仅返回该列的最大值,但不会影响其他列。要获得所需的结果,您需要运行以下命令:

SELECT name, AVG(quantity) as avgq 
FROM orders 
GROUP BY name
ORDER BY AVG(quantity) DESC
LIMIT 1;

答案 1 :(得分:3)

根据SQL标准,您的外部查询不正确。

因为您使用不带GROUP BY子句的聚合函数MAX(),所以MySQL假定隐式GROUP BY ()(SQL99标准和):

  

如果在不包含GROUP BY子句的语句中使用组函数,则相当于对所有行进行分组。

(来源:12.18.1 GROUP BY (Aggregate) Functions

只有在t.name子句中发生以下任何情况时,才能使用SELECT

MySQL接受SELECT字段不遵循上面列举的GROUP BY规则的查询,但在这种情况下,为这些字段返回的值是不确定的:

  

...使用MySQL的{​​{1}}扩展名是允许选择列表,GROUP BY条件或HAVING列表引用非聚合列,即使这些列在功能上不依赖于ORDER BY列。这会导致GROUP BY接受(...)查询。在这种情况下,服务器可以自由选择每个组中的任何值,因此除非它们相同,否则所选的值是不确定的,这可能不是您想要的。

(来源:12.18.3 MySQL Handling of GROUP BY

有效的查询

您可以保留内部查询,按MySQL降序生成的行,并使用SQL标准的另一个AVG(quantity)扩展名(即MySQL)来获取第一个值(是订购后的最大值。

查询是:

LIMIT

答案 2 :(得分:0)

您使用的查询实际上并不有效。您应该聚合所有未分组的列。在这种情况下,它适用于t.name

与其他更严格的数据库系统不同,MySQL允许运行此查询并获取它们在t.name字段中遇到的第一个值。当grouping或执行计划导致数据集的排序方式不同时,这可能会有所不同。

答案 3 :(得分:-1)

如果你真的想使用MAX()功能,但@Paul答案更好

select name, avg_quantity 
from (
   select name, avg(quantity) as avg_quantity from orders group by name
) as avg_table 
inner join (
   select max(avg_quantity) as avg_quantity 
   from (
      select name, avg(quantity) as avg_quantity from orders group by name) as avg_table
   ) as max_table USING (avg_quantity);