MYSQL 从每个类别中随机选择一条记录

问题描述 投票:0回答:6

我有一个带有

Items
表的数据库,看起来像这样:

id
name
category (int)

有几十万条记录。每个

item
可以属于 7 个不同的
categories
之一,对应于一个
categories
表:

id
category

我想要一个从每个类别中选择 1 个随机项目的查询。解决这个问题的最佳方法是什么?我知道使用

Order By rand()
LIMIT 1
进行类似的随机查询,但我从未做过这样的事情。

mysql sql random sql-order-by
6个回答
10
投票

此查询返回按随机顺序加入类别的所有项目:

SELECT
c.id AS cid, c.category, i.id AS iid, i.name
FROM categories c
INNER JOIN items i ON c.id = i.category
ORDER BY RAND()

要将每个类别限制为一个,请将查询包装在 partial

GROUP BY
:

SELECT * FROM (
    SELECT
    c.id AS cid, c.category, i.id AS iid, i.name
    FROM categories c
    INNER JOIN items i ON c.id = i.category
    ORDER BY RAND()
) AS shuffled_items
GROUP BY cid

请注意,当查询同时包含

GROUP BY
ORDER BY
子句时,将在排序之前执行分组。这就是我使用两个查询的原因:第一个查询对结果进行排序,第二个查询对结果进行分组。

我知道这个查询不会赢得任何比赛。我愿意接受建议。


0
投票

这是一个简单的解决方案。假设你有这张桌子。

id  name    category
1   A       1
2   B       1
3   C       1
4   D       2
5   E       2
6   F       2
7   G       3
8   H       3
9   I       3

使用此查询

select
  c.id,
  c.category,
  (select name from category where category = c.category   group by id order by rand() limit 1) as CatName
from category as c
group by category

0
投票

试试这个

SELECT id, name, category from Items where
( 
 select count(*) from Items i where i.category = Items.category 
 GROUP BY i.category ORDER BY rand()
) <= 1

参考:http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/


0
投票

在最终选择之前更改原始表格的顺序(随机顺序):

select * from 
  (select category, id, name from categories order by rand()) as tab 
  group by 1

0
投票

mysql8开始你可以使用Windows函数解决这个问题, 避免与

category
table

的额外连接条件

https://dev.mysql.com/doc/refman/8.0/en/window-functions-usage.html

     SELECT * FROM (
     SELECT FIRST_VALUE(id) OVER(PARTITION BY category ORDER BY RAND()) AS first_id FROM items
     Order BY RAND()) AS r
     GROUP BY first_id

-1
投票

请注意:在下面的示例中,我假设您的表被命名为“items”而不是“Items”,因为您还说另一个表被命名为“categories”(第二个表名称未大写)。

您想要执行的操作的 SQL 大致为:

`SELECT items.id AS item_id,
items.name AS item_name,
items.category AS item_category_id,
categories.id AS category_id,
categories.category AS category_name
FROM items, category
WHERE items.category = categories.id
ORDER BY rand()
LIMIT 1`
© www.soinside.com 2019 - 2024. All rights reserved.