查詢判斷條件等於時可能包含空值的情況處理
就是where后的條件語句,可能有空值null,也可能有正確的內容
場景
被這個需求搞得很頭大,正常情況下,關聯表查詢,我是這么寫的
SELECT
mp.xx, other_fields
FROM
cargo C
LEFT JOIN market_price mp ON c.product_id = mp.product_id and c.level_id = mp.level_id and c.brand_id = mp.brand_id
但是mp表的數據不是全部都有值,有的是空
然而數據庫對於空值null,進行操作都會返回null,所以就可以理解為這個關聯查詢的條件不生效,關聯查詢拿不到一條結果
= 一個值,但是這個值有可能為null,就不生效的問題
思路
錯誤的操作
- 我嘗試了使用如下sql代碼
SELECT
mp.xx, other_fields
FROM
cargo C
LEFT JOIN market_price mp ON ( ( C.brand_id IS NOT NULL AND C.brand_id = mp.brand_id ) OR C.brand_id IS NULL )
AND ( ( C.product_id IS NOT NULL AND C.product_id = mp.product_id ) OR C.product_id IS NULL )
AND ( ( C.level_id IS NOT NULL AND C.level_id = mp.level_id ) OR C.level_id IS NULL )
雖然拿到了數據,但是后知后覺提交了代碼測試的時候發現不對勁,存在重復的數據,GG
2. 我又嘗試在where中使用case when xx then result else other_result end
但很遺憾,數據依然有重復的
借鑒
最后在我絕望地百度了一堆帖,基本都是在講解COALESCE
如何將查詢到的結果轉換成另一個值,但是這並不符合我的情況,發現了如下一段很不起眼的內容
PostgreSQL WHERE和null
我將希望寄托在IS NOT DISTINCT FROM語句上
果然我就找到了解決的辦法!
postgresql 的 is distinct from、is not distinct from
如下為摘抄內容:
- is distinct from
功能描述
A和B的數據類型、值不完全相同返回 true
A和B的數據類型、值完全相同返回 false
將空值視為相同。
postgres=# \x
Expanded display is on.
postgres=# select 1 is distinct from 1,
1 is distinct from 2,
1 is distinct from '1',
'1' is distinct from '1',
1 is distinct from null,
null is distinct from null
;
-[ RECORD 1 ]
?column? | f
?column? | t
?column? | f
?column? | f
?column? | t
?column? | f
- is not distinct from
功能描述
A和B的數據類型、值不完全相同返回 false
A和B的數據類型、值完全相同返回 true
將空值視為相同。
postgres=# \x
Expanded display is on.
postgres=# select 1 is not distinct from 1,
1 is not distinct from 2,
1 is not distinct from '1',
'1' is not distinct from '1',
1 is not distinct from null,
null is not distinct from null
;
-[ RECORD 1 ]
?column? | t
?column? | f
?column? | t
?column? | t
?column? | f
?column? | t
拋開=
和is
符號的限制,進行判斷相等,這不就是我苦苦尋覓的滑板鞋嗎!?!?
結果
SELECT
mp.xx, other_fields
FROM
cargo C
LEFT JOIN market_price mp ON
-- (前 與 后 相等為 true) = true
(c.product_id is not DISTINCT from mp.product_id) = true and
(c.level_id is not DISTINCT from mp.level_id) = true and
(c.brand_id is not DISTINCT from mp.brand_id) = true
Nice 兄die~