当前位置: 首页 > 面试题库 >

PostgreSQL:插入两个或两个以上集合的笛卡尔积

微生毅
2023-03-14
问题内容

定义:两个集合的笛卡尔积是这些集合的所有可能对的集合,因此{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

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

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

问题答案:

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

对于来自T1和T2的行的每种可能组合(即 笛卡尔乘积
),联接表将包含一行,该行包含T1中的所有列,然后是T2中的所有列。如果表分别具有N行和M行,则联接表将具有N * M行。

FROM T1交叉联接T2等效于FROM T1,T2。它也等效于FROM T1 INNER JOIN T2 ON TRUE(请参见下文)。

编辑:

一种方法是使用VALUES列表(请注意,实际上您没有顺序,可以使用useORDER 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)


 类似资料:
  • 问题内容: 我可以通过以下方法轻松地在Scala中实现此目标: 因此,如果我给它{1,2},{3,4},我将返回{1,3},{1,4},{2,3},{2,4} 我希望能够使用流将其转换为java 8。 我有点困难,我希望能够进一步扩展,因为我希望能够从两个以上的列表中生成许多排列的测试样本。 即使使用流,是否也会不可避免地成为一团糟呢?还是我不够用自己? 在意识到我正在寻找笛卡尔积之后,发现了一些

  • 我可以在Scala中通过以下内容轻松实现这一点: 所以如果我给它{1,2},{3,4},我返回{1,3},{1,4},{2,3},{2,4} 我希望能够使用Streams将其转换为Java8。 我有一点困难,我希望能够扩展到更远的地方,因为我希望能够从两个以上的列表中生成许多排列的测试样本。 如何用Java8流制作笛卡尔积?

  • 问题内容: 与笛卡尔积一样,如何使用外壳一线和通用GNU工具将两个文件中的行连接起来?什么是最简洁,美观和“ linuxy”的方式? 例如,如果我有两个文件: 结果应该是 问题答案: 这是shell脚本 虽然那会很慢。我想不出任何预编译的逻辑来完成此任务。速度的下一步将是在awk / perl中执行上述操作。 嗯,这个使用预编译逻辑的hacky解决方案怎么样?

  • 问题内容: 我想在两个SELECT语句之间执行笛卡尔积 我希望结果是(1,2)与(3,4)的每种组合,例如: 问题答案: 您可以使用CROSS JOIN子句 其中MyTable1有两行,分别包含1和2;MyTable2有两行,分别包含3和4。

  • 现在我只能实现两个集合的笛卡尔积,下面是代码: 这段代码在IntelliJ中运行良好,但在Eclipse中不起作用。编译器符合性级别均为1.8: 这里是Pair.java: 如何修复此错误? 有没有一种优雅的方法来实现几个集合的笛卡尔产品?假设我们有类。

  • 现在我只能实现两个集合的笛卡尔积,下面是代码: 这段代码在IntelliJ中运行良好,但在Eclipse(两者的编译器遵从级别均为1.8)中就不行了: 下面是pair.java: 如何修复这个错误? 有没有一个优雅的方法来实现几个收藏的笛卡尔产品?(假设我们有类)