如何在MariaDB中从每个类别随机选取2条记录?
MariaDB按类别随机抽取指定数量记录的解决方案
场景说明
需要从test1表的每个类别中随机选取2条记录,实现类似Pandas分组抽样的效果,解决现有代码仅返回单个类别2条记录的问题。
示例数据集
假设test1表结构及数据如下:
CREATE TABLE test1 ( id INT AUTO_INCREMENT PRIMARY KEY, category VARCHAR(50), content VARCHAR(100) ); INSERT INTO test1 (category, content) VALUES ('A', '内容A1'), ('A', '内容A2'), ('A', '内容A3'), ('B', '内容B1'), ('B', '内容B2'), ('B', '内容B3'), ('B', '内容B4'), ('C', '内容C1'), ('C', '内容C2');
错误示例(仅返回单个类别数据)
如果直接用全局随机排序+LIMIT,只会得到随机2条,无法按类别分组:
SELECT * FROM test1 ORDER BY RAND() LIMIT 2;
正确实现方法
方法1:使用窗口函数(MariaDB 10.2+)
利用ROW_NUMBER()窗口函数按类别分组,每组内随机排序后取前2条:
SELECT id, category, content FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY category ORDER BY RAND()) AS rn FROM test1 ) t WHERE rn <= 2;
PARTITION BY category:按类别对数据分组ORDER BY RAND():每组内随机排序ROW_NUMBER():为每组内的记录分配递增序号,从1开始- 外层筛选
rn <= 2,保留每个类别中随机的前2条记录
方法2:兼容低版本MariaDB(10.2以下)
如果你的MariaDB版本不支持窗口函数,可使用用户变量实现分组计数:
SELECT id, category, content FROM ( SELECT *, @rn := IF(@current_cat = category, @rn + 1, 1) AS rn, @current_cat := category FROM test1, (SELECT @current_cat := '', @rn := 0) vars ORDER BY category, RAND() ) t WHERE rn <= 2;
- 初始化变量
@current_cat记录当前类别,@rn记录组内序号 - 按
category分组后,每组内随机排序,同一类别序号递增,切换类别时重置序号为1 - 最后筛选序号<=2的记录,实现每个类别随机取2条的效果
内容的提问来源于stack exchange,提问作者Lod
相关产品推荐
相关产品推荐

