MySQL 分组查询通常使用 GROUP BY
子句来对结果集进行分组,然后使用聚合函数(如 COUNT()
, SUM()
, AVG()
等)来计算每个分组的值。然而,直接使用 GROUP BY
并不能直接获取每个分组的前几条记录。
获取分组查询的前几条记录可以用于多种场景,例如:
常见的解决方法有两种:
LIMIT
和 ORDER BY
:通过子查询获取每个分组的排序结果,然后在外层查询中进行过滤。假设有一个销售记录表 sales
,结构如下:
CREATE TABLE sales (
id INT AUTO_INCREMENT PRIMARY KEY,
product_id INT,
category VARCHAR(50),
amount DECIMAL(10, 2),
sale_date DATE
);
我们需要获取每个类别中销售额最高的前两个产品。
SELECT product_id, category, amount
FROM (
SELECT product_id, category, amount,
ROW_NUMBER() OVER (PARTITION BY category ORDER BY amount DESC) as rn
FROM sales
) t
WHERE rn <= 2;
SELECT s.product_id, s.category, s.amount
FROM sales s
JOIN (
SELECT category, GROUP_CONCAT(product_id ORDER BY amount DESC SEPARATOR ',') as top_products
FROM (
SELECT product_id, category, amount,
@rank := IF(@cat = category, @rank + 1, 1) as rank,
@cat := category
FROM sales, (SELECT @rank := 0, @cat := '') r
ORDER BY category, amount DESC
) t
WHERE rank <= 2
GROUP BY category
) t2 ON FIND_IN_SET(s.product_id, t2.top_products);
如果你的 MySQL 版本低于 8.0,无法使用窗口函数,可以改用子查询的方法。
如果数据量很大,子查询可能会导致性能问题。可以考虑以下优化方法:
category
和 amount
列上有合适的索引。希望这些信息对你有所帮助!
领取专属 10元无门槛券
手把手带您无忧上云