gpt4 book ai didi

postgresql - 在 Postgres 中使用 UNION 或 INTERSECT 对具有列的表执行 SQL 重复消除

转载 作者:行者123 更新时间:2023-11-29 11:51:37 26 4
gpt4 key购买 nike

在 Postgres 中最简单的查询是

postgres=# select;
--
(1 row)

这个查询的结果是与一个单一的关系元组(行),即空元组。所以我们得到关系 {()}

这在语义上显然是正确的。

现在假设您有一个具有 1 个属性的关系 foo(值)和至少两个元组(行)。例如,

foo
----
value
------
1
2

现在发出以下查询

postgres=# select from foo;
--
(2 rows)

这是袋子 {(),()} 这是有道理的,因为我们在一组空属性上进行投影,foo 中有两个元组。

我想做的就是把这个包包成一套并获取 {()}。这可以通过如下方式进行分组:

postgres=# select from foo group by();
--
(1 row)

这也是正确的。

一般来说,另一种可能性是删除重复项就是使用SQL的UNIONINTERSECT运算符因为它们隐式地将包强制转换为集合。

例如,如果 R 是与重复项的关系,查询

(select * from R) UNION (select * R)

或查询

(select * from R) INTERSECT (select * R)

会成功的。

现在这是我的观察(和问题)。

考虑查询

(select from foo) UNION (select from foo)

人们会期望这个查询的答案是关系 {()},即删除重复的空元组。但是,什么时候在 postgresql 中执行此查询不要得到这个答案。

postgres=# (select from foo) UNION (select from foo);
--
(4 rows)

因此,在这种情况下,UNION 运算符似乎与 UNION ALL 运算符完全一样。

postgres=# (select from foo) UNION ALL (select from foo);
--
(4 rows)

但是 INTERSECT 发生了更奇怪的事情运算符(operator)。考虑查询

postgres=# (select from foo) INTERSECT (select from foo);
--
(4 rows)

所以你又一次得到了你期望的 4 个空元组仅 1 个(或最多 2 个)。

INTERSECT ALL 运算符也是如此

postgres=# (select from foo) INTERSECT ALL (select from foo);
--
(4 rows)

结论: 看起来有一个错误postgresql 归结为 UNIONINTERSECTINTERSECT ALL涉及没有属性的表的运算符。

备注:
人们可能想知道为什么要考虑这样的关系。但它们实际上非常有用,因为与零列的关系可以用作一种机制在查询处理中用 true 和 false 进行推理

关系 {()} 代表 true 和关系{} 代表 false

最佳答案

两者 UNIONINTERSECT 返回 4 行的事实似乎自相矛盾——要么空元组都相等(在这种情况下UNION 应该有更少的元素)或者空元组都不相等(在这种情况下 INTERSECT 应该有更少的元素)。

INTERSECT 的结果行比任何一个输入关系都 显然是疯了。

你应该把它带到 pgsql-hackers 列表或将它报告为一个错误。

但我不得不怀疑你所说的这些问题是否具有任何实用值(value):

  1. SELECT 列表不符合标准。它们是 PostgreSQL 中最近引入的实现工件。是什么阻止您使用(符合 SQL 标准的)变体 SELECT 1 FROM ...

  2. 如何将一个空元组的结果解释为 true 并将一个空结果解释为 false?两个空元组的结果是什么意思? UNIONINTERSECT 在此上下文中是什么意思?

关于postgresql - 在 Postgres 中使用 UNION 或 INTERSECT 对具有列的表执行 SQL 重复消除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39281688/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com