MySQL查询:如何从同一表的各分类中仅获取5条子记录?
解决方案
要实现每个Category ID下保留5条记录,核心是按分类分组后对组内记录编号,再筛选编号≤5的条目。直接用LIMIT或HAVING COUNT()无法实现分组限制——LIMIT是全局生效,HAVING仅用于聚合结果的过滤,无法针对组内单条记录做筛选。
方法一:窗口函数(推荐,适用于支持Window Functions的数据库)
MySQL 8.0+、PostgreSQL、SQL Server等主流数据库都支持窗口函数,用ROW_NUMBER()可以轻松实现需求:
SELECT `Product ID`, `Category ID`, Product FROM ( SELECT `Product ID`, `Category ID`, Product, ROW_NUMBER() OVER (PARTITION BY `Category ID` ORDER BY `Product ID`) AS row_num FROM CompanyXYZ.mkt_product ) AS ranked WHERE row_num <= 5;
代码说明:
PARTITION BY \Category ID``:按分类ID分组,每个分组单独计算编号ORDER BY \Product ID``:组内按Product ID排序(你可以换成其他字段,比如Product,只要每组能取到5条即可)- 子查询给每条记录生成组内编号
row_num,外层筛选编号≤5的记录
如果不需要严格排序,只是随机取5条,可以把ORDER BY换成ORDER BY RAND()(MySQL)或ORDER BY random()(PostgreSQL)。
方法二:兼容MySQL 5.x的替代方案(无窗口函数时使用)
如果你的MySQL版本低于8.0,不支持窗口函数,可以用自连接计数的方式:
SELECT t1.`Product ID`, t1.`Category ID`, t1.Product FROM CompanyXYZ.mkt_product t1 JOIN CompanyXYZ.mkt_product t2 ON t1.`Category ID` = t2.`Category ID` AND t1.`Product ID` >= t2.`Product ID` GROUP BY t1.`Product ID`, t1.`Category ID`, t1.Product HAVING COUNT(*) <= 5;
代码说明:
- 自连接同分类下的记录,统计每条记录在组内“小于等于自身Product ID”的条目数
- 筛选计数≤5的记录,实现每组取前5条(按Product ID排序)
内容的提问来源于stack exchange,提问作者SDK1993
相关产品推荐
相关产品推荐

