我想从同一个表中的每个类别中随机选择 5 条记录。
表名:t_shop
列名:shop_id、shop_categoryID
例如:shop_id | shop_categoryID
1 | 1
2 | 1
5 | 1
7 | 1
9 | 1
10| 1
13| 2
15| 2
22| 2
23| 2
25| 2
我曾尝试在子查询中使用限制,但出现错误:此版本的 MySQL 尚不支持 'LIMIT & IN/ALL/ANY/SOME 子查询
请问有什么办法可以解决吗?谢谢。
如果您有两个类别(如您的问题),MySQL 中最简单的方法是使用union all
:
(select * from t_shop where category = 1 order by rand() limit 5)
union all
(select * from t_shop where category = 2 order by rand() limit 5)
SELECT STRAIGHT_JOIN t.*
FROM (SELECT @r:=0, @c:= null) AS rownum_init,
(SELECT *, (@r:=IF(@c=shop_categoryID, @r+1, 1)) AS rownum, (@c:=shop_categoryID)
FROM t_shop
ORDER BY shop_categoryID, RAND()) AS t
WHERE t.rownum <= 5;
这是我在 MySQL 5.5.30 上测试的输出,使用您的测试数据:
+---------+-----------------+--------+-----------------------+
| shop_id | shop_categoryID | rownum | (@c:=shop_categoryID) |
+---------+-----------------+--------+-----------------------+
| 5 | 1 | 3 | 1 |
| 1 | 1 | 1 | 1 |
| 9 | 1 | 5 | 1 |
| 2 | 1 | 2 | 1 |
| 7 | 1 | 4 | 1 |
| 22 | 2 | 3 | 2 |
| 23 | 2 | 4 | 2 |
| 25 | 2 | 5 | 2 |
| 13 | 2 | 1 | 2 |
| 15 | 2 | 2 | 2 |
+---------+-----------------+--------+-----------------------+
通常,关于任何涉及的解决方案的建议ORDER BY ... RAND()
是它不可扩展,并且随着表大小的增长它变得更加昂贵。但是对于像您描述的那样复杂的随机选择问题,它可能仍然是解决问题的唯一方法。如果它表现不佳,请不要感到惊讶。
回复您的评论:
我不明白你的意思。Rownum 在每个类别中都有一个不同的值,从 1 开始,然后随着类别的变化从 1 开始。