Mysql SQL MAX()是如何工作的?

Mysql SQL MAX()是如何工作的?,mysql,max,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, '

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和SQLFIDLE得到的结果都是这样的

name    max(t.avgq)
-----+-------------
abc        8
它应该在哪里

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

这是为什么?

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

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

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

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

如果您确实想使用
MAX()
函数,但@Paul answer更好

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);

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

由于使用聚合函数时没有
GROUP BY
子句,因此(SQL99标准和MySQL)假定使用隐式
GROUP BY()

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

(来源:)

仅当出现以下情况时,才能在
SELECT
子句中使用
t.name

  • 它也出现在
    GROUP BY
    子句中
  • 它被用作a的参数
  • 它位于
    GROUP BY
    子句中出现的列上
MySQL接受那些
SELECT
字段不遵循上面列举的
groupby
规则的查询,但在这种情况下,这些字段返回的值是不确定的:

。。。
MySQL
对使用
groupby
的扩展是允许选择列表、
具有
条件或
orderby
列表引用未聚合的列,即使这些列在功能上不依赖于
groupby
列。这导致
MySQL
接受(…)查询。在这种情况下,服务器可以从每个组中自由选择任何值,因此,除非它们相同,否则选择的值是不确定的,这可能不是您想要的

(来源:)

有效的查询 您可以保留内部查询,将结果行按
AVG(quantity)
降序排列,并使用SQL标准的另一个
MySQL
扩展(即
LIMIT
)仅获取第一个值(排序后的最大值)

查询是:

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

MySQL在group by方面与其他dbms产品(或SQL标准)不一样,但SqlFIDLE也不起作用……即使是这个简单的产品也无法从订单中选择名称、最大数量;它返回abc 13根据SQL标准,查询无效(且未运行),因为为
t.name
选择的值不确定。MySQL接受查询并从
name
列中获取一些值。您能给我指一下那个SQL标准文档吗?许多人认为这不能保证产生正确的结果。如果是的话,那纯粹是偶然的。谢谢@Paul,我知道我们可以做到,但我一直认为从表中选择field1,max(field2);应该可以吗?或者我的sql知识是如此的错误?好吧,不是在MySQL中。正如其他人已经提到的,这将返回字段1的第一个值和字段2的最大值,这两个值不一定是相关的。实际上,我可以通过这样的查询来完成这一操作,如
SELECT name from orders,其中name=(SELECT max(avg_quantity)from(SELECT avg(quantity)As avg_quantity from orders GROUP BY name))
但是它太单调了。注意:
MAX
可以在没有
分组的情况下使用。谢谢您的详细解释