Postgres——查询判断条件等于时可能包含空值的情况处理

查询判断条件等于时可能包含空值的情况处理

就是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,就不生效的问题

思路

错误的操作

  1. 我尝试了使用如下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~

posted @ 2021-08-02 17:16  pywjh  阅读(2320)  评论(0编辑  收藏  举报
回到顶部