简体   繁体   English

选择 MYSQL 中具有最大值的所有行

[英]Selecting ALL rows which has a max value in MYSQL

table for visualization可视化表

item     title    numTimesPurchased
1        Beer     30
2        Chips    13
3        Smokes   30
4        Gum      3

Code I've written so far到目前为止我写的代码

SELECT Purchase.item, Item.title, SUM(quantity) AS numTimesPurchased 
FROM Item 
INNER JOIN Purchase ON Item.id = Purchase.item 
GROUP BY item, title;

I need to select all columns in the row/ multiple rows where which has a MAX value in numTimePurchased.我需要 select 行/多行中的所有列,其中在 numTimePurchased 中具有 MAX 值。 So in this table, both item 1 and 3 should be selected.所以在这个表中,第 1 项和第 3 项都应该被选中。

I've tried sorting the data using ORDER BY and LIMIT but it will not work with data sets where there are more than one row with a max value, is there another way to approach this problem?我尝试使用 ORDER BY 和 LIMIT 对数据进行排序,但它不适用于具有超过一个最大值的行的数据集,是否有另一种方法来解决这个问题?

One nice way to handle this on MySQL 8+ uses the RANK analytic function:在 MySQL 8+ 上处理此问题的一种好方法是使用RANK分析 function:

WITH cte AS (
    SELECT p.item, i.title, SUM(quantity) AS numTimesPurchased,
           RANK() OVER (ORDER BY SUM(quantity) DESC) rnk
    FROM Item i
    INNER JOIN Purchase p ON i.id = p.item
    GROUP BY p.item, i.title
)

SELECT item, title, numTimesPurchased
FROM cte
WHERE rnk = 1;

A way to handle this on earlier versions of MySQL uses a non correlated subquery in the HAVING clause to check the number of times purchased:在早期版本的 MySQL 上处理此问题的一种方法是在HAVING子句中使用非相关子查询来检查购买的次数:

SELECT p.item, i.title, SUM(quantity) AS numTimesPurchased
FROM Item i
INNER JOIN Purchase p ON i.id = p.item
GROUP BY p.item, i.title
HAVING SUM(quantity) = (SELECT SUM(quantity)
                        FROM Item i
                        INNER JOIN Purchase p ON i.id = p.item
                        GROUP BY p.item, i.title
                        ORDER BY SUM(quantity) DESC
                        LIMIT 1);
WITH cte AS ( SELECT Purchase.item, Item.title, SUM(quantity) AS numTimesPurchased 
                   , MAX(SUM(quantity)) OVER () maxsum
              FROM Item 
              INNER JOIN Purchase ON Item.id = Purchase.item 
              GROUP BY item, title )
SELECT * FROM cte WHERE numTimesPurchased = maxsum

MAX(SUM(quantity)) OVER () in CTE calculates maximal value (of SUM(quantity) = numTimesPurchased ) within all rows. CTE 中的MAX(SUM(quantity)) OVER ()计算所有行中的最大值( SUM(quantity) = numTimesPurchased )。 Outer query hence filters the rows where numTimesPurchased is not equal to this maximal value (formally not less needed, but the value above maximal value cannot exist).因此,外部查询过滤了numTimesPurchased不等于该最大值的行(通常不需要,但不能存在高于最大值的值)。

PS. PS。 I hope that quantity is not of float or double datatype.我希望quantity不是float 或 double 数据类型。 But if it is then SUM(quantity) (both expressions in CTE) must be rounded to reasonable accuracy.但如果是,则SUM(quantity) (CTE 中的两个表达式)必须四舍五入到合理的精度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM