1. 程式人生 > >in、not in、exists、not exists 在postgresql中的處理

in、not in、exists、not exists 在postgresql中的處理

os: centos 7.4
db: postgresql 11.1

# cat /etc/centos-release
CentOS Linux release 7.4.1708 (Core) 
# su - postgres -c "psql -c \"select version();\""
                                                 version                                                 
---------------------------------------------------------------------------------------------------------
 PostgreSQL 11.1 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-28), 64-bit
(1 row)

in、not in

with tmp_t0 as (
  select 'a'::varchar as c0 union all
  select 'b'::varchar as c0 union all
  select null as c0 
)
select *
  from tmp_t0 t0
 where 1=1
   and t0.c0 in ('a')
;

 c0 
----
 a
(1 row)

with tmp_t0 as (
  select 'a'::varchar as c0 union all
  select 'b'::varchar as c0 union all
  select null as c0 
)
select *
  from tmp_t0 t0
 where 1=1
   and t0.c0 not in ('a')
;

 c0 
----
 b
(1 row)

exists、not exists

with tmp_t0 as (
  select 'a'::varchar as c0 union all
  select 'b'::varchar as c0 union all
  select null as c0 
)
select *
  from tmp_t0 t0
 where 1=1
   and exists ( select 1 
                  from tmp_t0 t1 
				 where 1=1
				   and t1.c0 = 'a' 
				   and t0.c0 = t1.c0  
			   )
;

 c0 
----
 a
(1 row)


with tmp_t0 as (
  select 'a'::varchar as c0 union all
  select 'b'::varchar as c0 union all
  select null as c0 
)
select *
  from tmp_t0 t0
 where 1=1
   and not exists ( select 1 
                      from tmp_t0 t1 
				     where 1=1
				       and t1.c0 = 'a' 
					   and t0.c0 = t1.c0 
			       )
;

 c0 
----
 b
 
(2 rows)

根據這兩種結果猜測,就是在postgresql裡 null 值所在行壓根就沒有參與運算。

總結下和oracle在處理null時的異同點:

相同點:
in、exists 運算時,postgresql和oracle的處理方式相同,就是null值所在行壓根就沒有參與運算。

不同點:
not in、not exists 運算時,postgresql 排除null值所在行,然後參與運算,oracle只要發現運算列存在null值時,結果直接為空。