web-dev-qa-db-ja.com

既存のテーブルからランダムな値を選択して、新しいテーブル(複数の列)を作成します

私は次のタスク(PostgreSQL 9.3)で立ち往生しています。次のtable1(1万行)があるとしましょう。

表1:

id
754
800
330
4
59

私の目標は、2つの列(ソース、ターゲット)を持つ別のtable2を作成することです。ここで、両方の列の値は、table1.id値のランダムな選択です。例えば:

表2:

source | target
754    | 59
4      | 4
59     | 330

これは私がしたことです:

CREATE TABLE table2
(
  id serial NOT NULL,
  source integer,
  target integer,
  distance double precision
);

-- Select 300 table1.id values and insertion into table2.source  
INSERT INTO table2(source)
SELECT id FROM table1 ORDER BY RANDOM() LIMIT 300;

-- Select 300 table1.id values and updating table2.target 
UPDATE table2 SET target = i.id
FROM (SELECT id FROM table1 ORDER BY RANDOM() LIMIT 300) i;

次の結果が得られました。

source | target
754    | 59
330    | 59
800    | 59

残念ながら、すべてのtable2.target値はすべて同じです。 table2.targetを(例のように)異なるランダム値で更新するにはどうすればよいですか?または、おそらくUPDATEはこれを行うための良い方法ではありませんか?

2
Theo

"data-modifying CTE" をお勧めします:

WITH cte AS (
   SELECT *, row_number() OVER () AS rn
   FROM  (
      SELECT id
      FROM   tbl
      ORDER  BY random()
      LIMIT  600  -- 2 x 300
      ) sub
   )
INSERT INTO table2(source, target)
SELECT c1.id, c2.id
FROM   cte c1
JOIN   cte c2 ON c2.rn = c1.rn + 300;

CTEの場合:

  1. 600のランダムな行を選択します(300の新しい行を作成するため)
  2. 外側のSELECTに行番号を追加します。

次に、300オフセットの自己結合で2つの値を結合します。

巨大なテーブルからランダムな行を安価に取得するには、次のことを考慮してください。
PostgreSQLのランダムな行を選択する最良の方法

1