使用UNION或相交的Postgres最簡單的可能的查詢的列是SQL重複排除與Postgres的
postgres=# select;
--
(1 row)
這個查詢的結果是具有單個 元組(行)的關係,即,空元組。 所以我們得到關係{()}
。
這顯然是語義上正確的。
現在假設您有一個關係foo,其中包含1個屬性 (value)和至少兩個元組(行)。例如,
foo
----
value
------
1
2
現在發出以下查詢
postgres=# select from foo;
--
(2 rows)
這是包{(),()}
,這是有道理的,因爲 我們是在一個空的屬性集投影和有foo中兩個元。
我想要做的就是把這個袋子強制成一套 並獲得{()}
。 這可以用一組通過如下進行:
postgres=# select from foo group by();
--
(1 row)
這是正確的爲好。
另一種可能性,在一般情況下,刪除重複 是使用UNION
或INTERSECT
運營商SQL 的,因爲他們含蓄地強迫袋裝入套。
因此,舉例來說,如果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
操作。所以再次考慮查詢
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的一個bug,當它歸結到UNION
,INTERSECT
和INTERSECT ALL
運營商在事關表沒有任何屬性。
備註:
有人可能會問爲什麼會考慮這種關係。 但他們實際上是非常有用的,因爲零列的 關係可以用作查詢處理機制 辯解與真假
的關係{()}
代表true
和關係 {}
代表false
。
對不起,我不明白你的問題。請不要發明僞碼。 – wildplasser
@wildplasser其實它是工作代碼。 – Abelisto
比較'未知'和'未知'提供了'未知'結果[(Three-valued logic)](https://en.wikipedia.org/wiki/Three-valued_logic)這是因爲'未知'值的系列假設因爲它們都不同(或不同於其他方面)。 – Abelisto