加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Postgresql:插入两组或更多组的笛卡尔积

发布时间:2020-12-13 15:58:27 所属栏目:百科 来源:网络整理
导读:作为定义:两组的笛卡尔积是这些集的所有可能对的集合,因此{A,B} x {a,b} = {(A,a),(A,b),(B,a ),(b,b)}. 现在我想将这样的笛卡尔积插入数据库表(每对作为一行).打算用每个对的默认值填充表,因此此时数据(即两组)不存在于数据库中. 任何想法如何用postgresql
作为定义:两组的笛卡尔积是这些集的所有可能对的集合,因此{A,B} x {a,b} = {(A,a),(A,b),(B,a ),(b,b)}.

现在我想将这样的笛卡尔积插入数据库表(每对作为一行).打算用每个对的默认值填充表,因此此时数据(即两组)不存在于数据库中.

任何想法如何用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

有没有更好的方法来做到这一点?

编辑2:
接受的答案很好,但我找到了另一个版本,如果它变得更复杂可能是合适的:

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";

解决方法

我不确定这是否真的能回答你的问题,但在PostgreSQL中有 CROSS JOIN定义为:

For every possible combination of rows from T1 and T2 (i.e.,a
Cartesian product),the joined table will contain a row consisting of
all columns in T1 followed by all columns in T2. If the tables have N
and M rows respectively,the joined table will have N * M rows.

FROM T1 CROSS JOIN T2 is equivalent to FROM T1,T2. It is also
equivalent to FROM T1 INNER JOIN T2 ON TRUE (see below).

编辑:

一种方法是使用VALUES Lists(注意事实上你没有订单,使用ORDER BY子句来获得一些排序):

SELECT N AS number,L AS letter FROM
    (VALUES (1),(3)) a(N)
CROSS JOIN
    (VALUES ('A'),('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)

BTW:

对于更多数字,我认为使用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)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读