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
为什么?
答案 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
:
GROUP BY
子句中; GROUP BY
aggregate function; GROUP BY
子句中显示的列上的functionally dependent。 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);