Postgresql
IS NOT DISTINCT FROM vs row-wise equal with =
查看以下查詢,
SELECT null IS NOT DISTINCT FROM null AS indf, null = null AS eq; indf | eq ------+---- t |
從這裡我們可以看到
IS NOT DISTINCT FROM
is的結果,以及istrue
的結果。然後從邏輯上遵循以下內容,eq``false
-- 1 rows SELECT * FROM ( VALUES (null) ) AS t(a) JOIN ( VALUES (null) ) AS g(a) ON t.a IS NOT DISTINCT FROM g.a; -- 0 rows SELECT * FROM ( VALUES (null) ) AS t(a) JOIN ( VALUES (null) ) AS g(a) ON t.a = g.a;
因為如果條件返回
null
失敗join
。但是,這讓我失望,逐行比較-- returns 1 row. SELECT * FROM ( VALUES (null) ) AS t(a) JOIN ( VALUES (null) ) AS g(a) ON (t) IS NOT DISTINCT FROM (g); -- also returns one row. SELECT * FROM ( VALUES (null) ) AS t(a) JOIN ( VALUES (null) ) AS g(a) ON (t) = (g);
為什麼按行比較對待
null
s 與標量比較不同?是否有IS NOT DISTINCT FROM
逐行比較的意義?
NULL
如果結果取決於比較兩個值或 aNULL
和非,則 SQL 規範要求逐行比較返回 NULLNULL
。PostgreSQL 僅在比較兩個行建構子的結果(如 9.23.5 節)或將行建構子與子查詢的輸出進行比較(如 9.22 節)時才會這樣做。在比較兩個複合類型值的其他上下文中,兩個NULL
欄位值被認為是相等的,並且 aNULL
被認為大於非NULL
. 為了使復合類型具有一致的排序和索引行為,這是必要的。這實質上意味著標準行為只能在以下語法中看到(
ROW()
是行建構子):SELECT * FROM ( VALUES (null) ) AS t(a) JOIN ( VALUES (null) ) AS g(a) ON ROW(t.*) = ROW(g.*);
相對,
SELECT * FROM ( VALUES (null) ) AS t(a) JOIN ( VALUES (null) ) AS g(a) ON ROW(t.*) IS NOT DISTINCT FROM ROW(g.*);
僅使用帶有類型的 ROW 建構子也不起作用
ON ROW(t) = ROW(g)