MYSQL 从每个类别中选择一个随机记录
Posted
技术标签:
【中文标题】MYSQL 从每个类别中选择一个随机记录【英文标题】:MYSQL Select One Random record from each Category 【发布时间】:2012-12-24 02:15:10 【问题描述】:我有一个带有Items
表的数据库,看起来像这样:
id
name
category (int)
有几十万条记录。每个item
可以是7 个不同的categories
之一,它们对应一个categories
表:
id
category
我想要一个从每个类别中选择 1 个随机项目的查询。解决这个问题的最佳方法是什么?我知道使用Order By rand()
和LIMIT 1
进行类似的随机查询,但我从来没有做过这样的事情。
【问题讨论】:
【参考方案1】:此查询以随机顺序返回所有加入类别的项目:
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()
要将每个类别限制为一个,请将查询包装在 部分 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
子句时,会在排序之前执行分组。这就是我使用两个查询的原因:第一个对结果进行排序,第二个对结果进行分组。
我知道这个查询不会赢得任何比赛。我愿意接受建议。
【讨论】:
上述查询经过几次更正后有效:SELECT * FROM ( SELECT c.id as cid, c.category, i.id, i.name FROM categories c INNER JOIN Items i ON c.id = i.category ORDER BY RAND() ) AS ShuffeledItems GROUP BY ShuffeledItems.cid
嗯,这个修改后的查询为我返回了大约 1500 行
@SalmanA 是的,我不知道该说什么。我正在我的数据库上尝试它,它返回大约 1500 行,而不是 7。
这很奇怪,因为这里是按类别 ID 分组的,所以如果你得到大约 1500 行,你就有 1500 个类别...
@rzymek 啊没关系,你是对的。我的表中的语法略有不同,这导致了问题!非常感谢!【参考方案2】:
这是一个简单的解决方案。假设你有这张桌子。
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
【讨论】:
这个我很难理解,因为似乎没有提到items
表,只有 categories
表
@dtj 我的查询中没有关键字项目,那么您有什么困惑?我已经给你举了一个例子,你当然可以在它之后自己锻炼。
您确定GROUP BY
和RAND()
会一起为每个组随机分配一个吗?因为我怀疑它。【参考方案3】:
试试这个
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/
【讨论】:
这一项,报错子查询返回多于1行【参考方案4】:在最终选择之前更改原始表的顺序(随机顺序):
select * from
(select category, id, name from categories order by rand()) as tab
group by 1
【讨论】:
请用一些 cmets 更新您的答案以及它是如何回答问题的。【参考方案5】:请注意:在以下示例中,我假设您的表名为“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`
【讨论】:
这个查询只返回一行。没有 LIMIT 1 - 每个类别的所有项目... @ryzmek,是的,没错。巧合的是,这也是OP所要求的。 OP 说,我引用:“我想要一个从每个类别中选择 1 个随机项目的查询” 在我看来,作者希望查询返回 7 行,每个类别一个 rand 项。 抱歉,如果不清楚。查询应返回 7 行 -- 每个类别对应 1 行 这个查询只返回一行以上是关于MYSQL 从每个类别中选择一个随机记录的主要内容,如果未能解决你的问题,请参考以下文章
postgresql 对大型数据集进行分区并从一个类别中随机选择 3 个