为每组选择随机行

Posted

技术标签:

【中文标题】为每组选择随机行【英文标题】:Select random row for each group 【发布时间】:2013-04-09 07:37:11 【问题描述】:

我有一张这样的桌子

ID    ATTRIBUTE
 1    A
 1    A
 1    B
 1    C
 2    B
 2    C
 2    C
 3    A
 3    B
 3    C

我想为每个 ID 选择一个随机属性。因此,结果可能如下所示(尽管这只是众多选项之一

ATTRIBUTE
B
C
C

这是我对这个问题的尝试

SELECT
  "ATTRIBUTE"
FROM
  (
  SELECT
    "ID",
    "ATTRIBUTE",
    row_number() OVER (PARTITION BY "ID" ORDER BY random()) rownum
  FROM
    table
  ) shuffled
WHERE
  rownum = 1

不过,我不知道这是否是一个好的解决方案,因为我需要引入行号,这有点麻烦。

你有更好的吗?

【问题讨论】:

【参考方案1】:
select distinct on (id) id, attribute
from like_this
order by id, random()

如果只需要属性列:

select distinct on (id) attribute
from like_this
order by id, random()

请注意,您仍然需要先通过id 订购,因为它是distinct on 的一列。

如果你只想要不同的属性:

select distinct attribute
from (
    select distinct on (id) attribute
    from like_this
    order by id, random()
) s

【讨论】:

但这会以随机顺序返回每个属性,而不仅仅是每个 ID 一个,还是我误解了您的代码? @speendo distinct on (id) 使其每个 id 只返回一行 笑成这样:D mysql中没有这样的语法吗? :)【参考方案2】:

在每条记录(id)前面放一个大的随机数,然后在每组中选择随机数最小的记录。

$ cat test.txt
\N  1   a
\N  2   b
\N  2   c
\N  2   d
\N  3   e
\N  4   f


$ mysql

USE test;
DROP TABLE test;
CREATE TABLE test (id0 INT NOT NULL AUTO_INCREMENT, id VARCHAR(1),  attribute VARCHAR(1), PRIMARY KEY (id0));
LOAD DATA LOCAL INFILE '~/mysql/test.txt' INTO TABLE test FIELDS TERMINATED BY '\t';

DROP TABLE rtest;
CREATE TABLE rtest (random INT(8), id0 VARCHAR(1), id VARCHAR(1),  attribute VARCHAR(1),  PRIMARY KEY (id, random));

INSERT INTO rtest
SELECT CAST(1000000. * rand() AS INT) AS random, test.* FROM test;

SELECT rtest.* FROM rtest,
(SELECT id, min(random) AS random FROM rtest GROUP BY id) AS sample WHERE rtest.random=sample.random AND rtest.id=sample.id;

【讨论】:

结果是否总是具有相同的顺序,即使第一次是随机的。

以上是关于为每组选择随机行的主要内容,如果未能解决你的问题,请参考以下文章

从数据库中选择一个随机行

从文件中选择随机行

如何使用纯 SQL 选择 N 个随机行?

MySQL - 从大表中选择随机行

从 sqlite 表中选择随机行

Pandas 数据框中的随机行选择