【发布时间】:2017-05-10 15:38:00
【问题描述】:
我需要在他们的组中找到价值最大的行。
我做了很多研究,找到了很多解决方案:join、临时表等。
我仍然想用“order by ... having ...”来尝试一些东西,但我发现了一些奇怪的东西。
这是我的查询:
SELECT MAX(id) AS MaxValue, MyTable.*
FROM MyTable
GROUP BY name
HAVING id = MaxValue
我得到一个行列表作为结果,但我没有每个名字都有一行。
当我这样做时,我获得了很多行:
SELECT * FROM MyTable WHERE name = 'John'
但是第一个查询的结果不包含任何名为“John”的行,如果我这样做,我什么也得不到:
SELECT MAX(id) AS MaxValue, MyTable.*
FROM MyTable
GROUP BY name
HAVING id = MaxValue AND name = 'John'
我真的不明白它是如何工作的,它触发了我。
谁能解释我这种行为?
我没有问“怎么做”。我只是不明白“通过...拥有分组”是如何工作的。
【问题讨论】:
-
“我需要在它们的组中找到具有最大价值的行。” --
GROUP BY对此无济于事。它不会从表中返回行,而是使用每个组中的数据生成新行。它计算来自SELECT子句的每个表达式,独立于其他表达式。作为一般规则,SELECT * ... GROUP BY是无效的 SQL。 -
你对
SELECT * ... GROUP BY说“无效”是什么意思?我使用 mySQL 并没有收到任何错误。你的意思是这是不好的做法? -
Invalid 表示不正确。 SQL 标准对可以出现在
GROUP BY查询的SELECT子句中的表达式设置了一些限制(这是有充分理由的)。大多数 RDBMS 遵循标准并拒绝无效查询。在 5.7.5 版本之前,MySQL 接受它们,但 takes its freedom to return indeterminate results。从 5.7.5 开始,行为是可配置的(默认情况下它会拒绝它们),我猜将来它不会再接受它们了。阅读更多:dev.mysql.com/doc/refman/5.7/en/group-by-handling.html -
我明白了。我想当我这样做时也会出现同样的问题:
SELECT id, MAX(id) AS MaxValue, FROM MyTable GROUP BY name HAVING id = MaxValue -
看看this answer。如果您查询单个表,那么您会从该答案中获得想法并编写符合您需求的查询。这是完成这项工作的最快方法。如果您需要查询多个表(使用
JOINs),那么您最好尝试以下答案中提供的查询之一。他们不会跑那么快,但他们会在没有其他问题的情况下完成这项工作。
标签: mysql group-by greatest-n-per-group