比较空值的奇怪行为SQL

时间:2018-09-26 07:58:43

标签: sql postgresql null

我正在比较两个表格,并且得到一个奇怪的结果。我首先比较了两个通常为空的列。声明null = null总是返回false。我发现这些列的工作方式为IS NULL。结果显示了很多双行,我不明白。

所以基本上这行data.data_1

column1     column2     column3     column4
apple       tree        NULL        NULL        

和这一行data.data_2

column1     column2     column3     column4
apple       tree        NULL        NULL        

在以下查询后返回

select
    br.column1, br.column2, br.column3, br.column4,  
    af.column1, af.column2
from
    data.data_1 as br
    left join data.data_2 as af on 
        (br.column1 = af.column1 and
        br.column2 = af.column2 and
        br.column3 IS NULL and af.column3 IS NULL and 
        br.column4 IS NULL and af.column4 IS NULL)

column1     column2     column3     column4     af.column1     af.column2     
apple       tree        NULL        NULL         apple          tree 
apple       tree        NULL        NULL         apple          tree 
apple       tree        NULL        NULL         apple          tree      
apple       tree        NULL        NULL         apple          tree      
apple       tree        NULL        NULL         apple          tree      
apple       tree        NULL        NULL         apple          tree      
apple       tree        NULL        NULL         apple          tree      
apple       tree        NULL        NULL         apple          tree      
apple       tree        NULL        NULL         apple          tree      
apple       tree        NULL        NULL         apple          tree      
apple       tree        NULL        NULL         apple          tree      
apple       tree        NULL        NULL         apple          tree      
apple       tree        NULL        NULL         apple          tree      
apple       tree        NULL        NULL         apple          tree      
apple       tree        NULL        NULL         apple          tree    

代替我希望它返回的是:

column1     column2     column3     column4     af.column1     af.column2     
apple       tree        NULL        NULL         apple          tree 

我可以在其周围添加一个独特的功能,但我感觉这将是不必要的额外操作。

3 个答案:

答案 0 :(得分:2)

demo: db<>fiddle

SELECT *
FROM br
LEFT JOIN af
ON 
    br.col1 = af.col1 
AND br.col2 = af.col2 
AND COALESCE(br.col3, af.col3, br.col4, af.col4) IS NULL

COALESCE() IS NULL确保此函数(所有列)中的所有元素均为NULL

答案 1 :(得分:1)

如果要比较两个可为空的列,并考虑NULL = NULL,则使用IS NOT DISTINCT FROM

SELECT CASE WHEN NULL = NULL                    THEN 'Equal' ELSE 'IDK' END       -- IDK
SELECT CASE WHEN NULL IS NOT DISTINCT FROM NULL THEN 'Equal' ELSE 'Not Equal' END -- Equal

只需将此条件插入原始查询中即可:

select
    br.column1, br.column2, br.column3, br.column4,
    af.column1, af.column2
from
    data.data_1 as br
    left join data.data_2 as af on (
        br.column1 = af.column1 and
        br.column2 = af.column2 and
        br.column3 IS NOT DISTINCT FROM af.column3 and
        br.column4 IS NOT DISTINCT FROM af.column4
    )

答案 2 :(得分:0)

left join使查询列出data_1中的所有行,无论data_2中是否有匹配的行。

此外,仅当两个表中的column3column4NULL时,您才加入-并列出这些NULL值。温和地说,这有点令人困惑。

如果您要写下想要实现的目标,您的问题将容易回答。