如何在 MySQL 查询中找到最大总和的关联名称?

Posted

技术标签:

【中文标题】如何在 MySQL 查询中找到最大总和的关联名称?【英文标题】:How do I find the associated name of a max of a sum in a MySQL query? 【发布时间】:2020-10-05 09:54:48 【问题描述】:

我这里有这个架构,我需要找到订单总额最高的客户的姓名。我这里有一个 SQL 查询:

SELECT Name
FROM (SELECT Name, SUM(Amount) AS Total
      FROM customer JOIN orders ON cust_id = ID
      GROUP BY Name) AS Totals
WHERE Total = (SELECT MAX(Total)
                      FROM (SELECT Name, SUM(Amount) AS Total
                            FROM customer JOIN orders ON cust_id = ID
                            GROUP BY Name) AS X);

但这非常低效,因为它两次创建同一个表。有没有更有效的取名方式?

【问题讨论】:

您的 DBMS 可能会看到有 2 次相同的查询并为您优化它 如果可以有超过一个客户的最大总数,那就不行了。 如果您使用的是 mysql 8.0,您可以将重复查询放在 CTE 中。 在 MySQL 5.x 中,您可以使用 VIEW。 @Barmar View 不保证任何事情,MySQL 将其用作不重复查询的“快捷方式” 【参考方案1】:

如果您想要总安装量最大的客户,那么您可以加入、订购和限制:

select c.name
from customer c
inner join orders o on o.cust_id = c.id
group by c.id, c.name
order by sum(o.amount) desc 
limit 1

请注意,这不处理可能的顶部关系。为此,您需要更多代码。您通常会使用 having 子句进行过滤,而不是排序:

select c.name
from customer c
inner join orders o on o.cust_id = c.id
group by c.id, c.name
having sum(o.amount) = (
    select sum(o1.amount)
    from orders o1
    group by cust_id
    order by sum(o1.amount) desc
    limit 1
)

最后:如果您运行的是 MySQL 8.0,使用窗口函数rank() 会更简单:

select name
from (
    select c.name, rank() over(order by sum(o.amount) desc) rn
    from customer c
    inner join orders o on o.cust_id = c.id
    group by c.id, c.name
) t
where rn = 1

【讨论】:

如果有多个客户有最大值怎么办? @Barmar 好吧,他询问了客户的姓名(单数),所以这个问题实际上是正确的 @Barmar:我的编辑涵盖了(我正在打字,而你正在评论......)。 带有having的版本和原代码有同样的问题,因为它必须重复sum子查询。 @pastacompany:它处理两个客户同名的情况。在这样的group by 子句中拥有主键总是一个好主意。

以上是关于如何在 MySQL 查询中找到最大总和的关联名称?的主要内容,如果未能解决你的问题,请参考以下文章

如何查询mysql一个字段的最大值的总和

mysql从表中显示数据最大值和总和

MySQL 聚合函数 和 分组查询(初级)

MySQL 聚合函数 和 分组查询(初级)

MySQL 聚合函数 和 分组查询(初级)

如何获取每年的积分名称和最大总和值?