如何在同一次查询请求中同时使用max和count函数获取下单量最高的商品

解决方案
先假设用到的核心表结构如下,你可以根据实际表结构按需调整字段:
- 商品表
products:存储商品基础信息,核心字段为product_id(商品唯一ID)、product_name(商品名称) - 订单明细表
order_items:存储每笔订单对应的商品信息,核心字段为order_item_id、product_id(关联商品表)、quantity(单条记录对应下单商品数量)
通用写法(兼容所有主流数据库)
不需要依赖窗口函数,适配MySQL 5.x、Oracle、SQL Server等所有常见数据库:
SELECT p.product_id, p.product_name, COUNT(o.order_item_id) AS order_count FROM products p INNER JOIN order_items o ON p.product_id = o.product_id GROUP BY p.product_id, p.product_name HAVING COUNT(o.order_item_id) = ( SELECT MAX(item_count) FROM ( SELECT COUNT(order_item_id) AS item_count FROM order_items GROUP BY product_id ) AS t )
逻辑说明
- 最内层子查询先统计每个商品的下单次数,得到所有商品的下单次数集合
- 外层子查询从上述集合中取出最大的下单次数值
- 最外层查询统计每个商品的下单次数,过滤出和最大值相等的记录即可,存在多个并列销量第一的商品也会全部返回
简洁写法(支持窗口函数的数据库,如MySQL 8.0+、PostgreSQL、SQL Server 2012+)
用RANK()窗口函数实现,代码更简洁,性能也更优:
WITH product_order_stat AS ( SELECT p.product_id, p.product_name, COUNT(o.order_item_id) AS order_count, RANK() OVER(ORDER BY COUNT(o.order_item_id) DESC) AS ranking FROM products p INNER JOIN order_items o ON p.product_id = o.product_id GROUP BY p.product_id, p.product_name ) SELECT product_id, product_name, order_count FROM product_order_stat WHERE ranking = 1
如果不需要保留并列第一的结果,仅需返回任意一个最高销量的商品,把RANK()替换为ROW_NUMBER()即可。
如果需求是统计商品的总下单件数而非下单次数,把上述代码中的COUNT(o.order_item_id)替换为SUM(o.quantity)即可。
内容的提问来源于stack exchange,提问作者bilalbajou
相关产品推荐
相关产品推荐

