5

定義として: 2 つのセットのデカルト積は、これらのセットのすべての可能なペアのセットであるため、{A,B} x {a,b} = {(A,a),(A,b),(B,a ),(B,b)}.

今、私はそのようなデカルト積をデータベーステーブルに挿入したいと思っています(各ペアを行として)。各ペアのデフォルト値をテーブルに入力することを目的としているため、この時点ではデータ、つまり 2 つのセットはデータベースに存在しません。

postgresqlでこれを達成する方法はありますか?

編集 :

Grzegorz Szpetkowski の回答の助けを借りて、私が達成したいことを行うクエリを作成することができましたが、実際には最も美しいものではありません。セット {1,2,3} と {'A','B','C'} のデカルト積を挿入するとします。

INSERT INTO "Test"
SELECT * FROM
(SELECT 1 UNION SELECT 2 UNION SELECT 3) P
CROSS JOIN
(SELECT 'A' UNION SELECT 'B' UNION SELECT 'C') Q

これを行うより良い方法はありますか?

EDIT2: 受け入れられた答えは問題ありませんが、より複雑になった場合に適切な別のバージョンを見つけました:

CREATE TEMP TABLE "Numbers" (ID integer) ON COMMIT DROP;
CREATE TEMP TABLE "Chars" (Char character varying) ON COMMIT DROP;
INSERT INTO "Numbers" (ID) VALUES (1),(2),(3);
INSERT INTO "Chars" (Char) VALUES ('A'),('B'),('C');
INSERT INTO "Test"
SELECT * FROM
"Numbers"
CROSS JOIN
"Chars";
4

1 に答える 1

11

これが本当にあなたの質問に答えるかどうかはわかりませんが、PostgreSQL では次のようにCROSS JOIN定義されています。

T1 と T2 の行の可能な組み合わせ (つまり、 デカルト積) ごとに、結合されたテーブルには、T1 のすべての列とそれに続く T2 のすべての列で構成される行が含まれます。テーブルにそれぞれ N 行と M 行がある場合、結合されたテーブルには N * M 行が含まれます。

FROM T1 CROSS JOIN T2 は、FROM T1、T2 と同等です。また、FROM T1 INNER JOIN T2 ON TRUE (下記参照) と同等です。

編集:

1 つの方法は、VALUES リストを使用することです (実際には順序がないことに注意してください。ORDER BY句を使用して順序を取得します)。

SELECT N AS number, L AS letter FROM
    (VALUES (1), (2), (3)) a(N)
CROSS JOIN
    (VALUES ('A'), ('B'), ('C')) b(L);

結果:

 number | letter
--------+--------
      1 | A
      1 | B
      1 | C
      2 | A
      2 | B
      2 | C
      3 | A
      3 | B
      3 | C
(9 rows)

ところで

generate_seriesより多くの数値については、関数を使用するためのハンドルだと思います。

SELECT n AS number, chr(ascii('A') + L - 1) AS letter
FROM
    generate_series(1, 5) N
CROSS JOIN
    generate_series(1, 5) L
ORDER BY N, L;

結果:

 number | letter
--------+--------
      1 | A
      1 | B
      1 | C
      1 | D
      1 | E
      2 | A
      2 | B
      2 | C
      2 | D
      2 | E
      3 | A
      3 | B
      3 | C
      3 | D
      3 | E
      4 | A
      4 | B
      4 | C
      4 | D
      4 | E
      5 | A
      5 | B
      5 | C
      5 | D
      5 | E
(25 rows)
于 2011-07-13T18:08:29.757 に答える