某个列的分组最大值

时间:2011-09-29 08:27:09

标签: mysql group-by greatest-n-per-group

我有桌子:

SELECT * FROM shop;

+---------+--------+------
| article | dealer | price
+---------+--------+------
|    0001 | A      |  3.45
|    0001 | B      |  3.99
|    0002 | A      | 10.99
|    0003 | B      |  1.45
|    0003 | C      |  1.69
|    0003 | D      |  1.25
|    0004 | D      | 19.95
+---------+--------+------
7 rows in set (0.20 sec)

我希望 - 每篇文章 - 价格最贵的经销商或经销商。

有谁可以告诉我为什么这不起作用?

SELECT article, dealer, MAX(price) FROM shop GROUP BY(article);

对于此查询,我得到以下结果集;

+---------+--------+------------+
| article | dealer | MAX(price) |
+---------+--------+------------+
|    0001 | A      |       3.99 |
|    0002 | A      |      10.99 |
|    0003 | B      |       1.69 |
|    0004 | D      |      19.95 |
+---------+--------+------------+
4 rows in set (0.03 sec)

虽然最高价格是正确的,但我找错了经销商的一些文章。

5 个答案:

答案 0 :(得分:4)

根据您的问题,您似乎已经阅读了有关group-wise maximum of a certain column的文章,但是您只是不明白为什么您提到的方法无法按预期工作。

让我们想象一下这样的查询:

SELECT article, dealer, MAX(price), MIN(price) 
FROM shop 
GROUP BY article

您期望经销商有什么价值?

我认为这可以回答你的问题。

答案 1 :(得分:2)

你走了:

SELECT article, dealer, price
FROM (SELECT article, dealer, price
      FROM shop
      ORDER BY price DESC) AS h
GROUP BY article

此解决方案甚至不需要MAX()函数。 :)

注意:此解决方案不适用于ONLY_FULL_GROUP_BY活动,仅适用于MySQL。由于缺乏确认此行为的文档,此解决方案在某种程度上不受支持。它适用于我,但对我来说一直很好。

此方法仍适用于最新的MySQL on sqlfiddle

答案 2 :(得分:1)

标准SQL会拒绝您的查询,因为您不能SELECT非聚合字段,而这些字段不属于聚合查询中GROUP BY子句的一部分。

您正在使用描述here的SQL的MySQL扩展:

  

MySQL扩展了GROUP BY的使用,以便选择列表可以引用   未在GROUP BY子句中命名的非聚合列。这意味着   前面的查询在MySQL中是合法的。您可以使用此功能   通过避免不必要的列排序来获得更好的性能   分组。但是,这主要适用于每个中的所有值   GROUP BY中未命名的非聚合列对于每个列都是相同的   组。 服务器可以自由选择每个组中的任何值,所以   除非它们相同,否则选择的值是不确定的

答案 3 :(得分:0)

这不起作用,因为如果使用group by,则不能使用原始行的各个字段(除了要分组的字段)。这样做的正确方法是做一个内部/嵌套查询来选择经销商,这很糟糕(我没有测试过,所以它可能会略微偏离):

SELECT article, MAX(price) as maxPrice, (SELECT dealer FROM shop AS s2 WHERE s2.article = s1.article AND s2.price = maxPrice) AS expensiveDealer FROM shop AS s1 GROUP BY(article);

答案 4 :(得分:0)

我只是翻过这个问题,并想知道为什么没有人想到如某些教程中所描述的那样加入表格(见下面的链接)。

所以我建议采用以下解决方案:

Select A.* 
From      shop As A 
Left Join shop As B On  A.article
                     =  B.Article 
                    AND A.price 
                      < B.price 
Where B.price Is Null;

神奇之处显而易见:将表连接到自身并将其中的任何记录链接到任何其他具有更高价格的记录。从那些中,只抓住没有链接记录且价格较高的那些(这些记录是价格最高的记录)。

据我所知,这种解决方案在性能方面甚至是最好的。

This part of the MySQL documentation和/或非常interesting article by Jan Kneschke可能会有所帮助 - 尽情享受!