9

このようなテーブルがあります

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

ID ごとにランダムな属性を1 つだけ選択したいと思います。したがって、結果は次のようになります (ただし、これは多くのオプションの 1 つにすぎません)。

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

ただし、行番号を導入する必要があるため、これが良い解決策かどうかはわかりません。これは少し面倒です。

もっと良いものはありますか?

4

2 に答える 2

20
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
于 2013-04-16T18:54:52.277 に答える
-1

各レコード (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;
于 2017-05-11T10:02:09.537 に答える