SQL JOIN匹配NULL列值

时间:2018-07-05 15:39:02

标签: sql join sql-server-2012 null sql-delete

我正在MS SQL Server 2012中使用JOIN来删除一个表中的记录,该记录与使用另一个表中的记录相匹配

DELETE t1
FROM Table1 t1
JOIN Table2 t2
    ON 
    t1.[Column1] = t2.[Column1] 
    AND t1.[Column2] = t2.[Column2] 
    AND t1.[Column3] = t2.[Column3] 

但是,如果两个表中的列都包含null,则它们将不匹配并被删除。如果两列都包含null,如何在不添加对null

的特定检查的情况下修改查询以匹配记录
DELETE t1
FROM Table1 t1
JOIN Table2 t2
    ON 
    t1.[Column1] = t2.[Column1] OR (t1.[Column1] is null and t2.[Column1] is null)
    AND t1.[Column2] = t2.[Column2] OR (t1.[Column2] is null and t2.[Column2] is null)
    AND t1.[Column3] = t2.[Column3] OR (t1.[Column3] is null and t2.[Column3] is null)

3 个答案:

答案 0 :(得分:3)

您可以使用SET ANSI_NULLS OFF使=对待两个null相等。

答案 1 :(得分:2)

这是一个实际的问题,因为SQL Server没有安全可靠的NULL比较运算符。 ANSI标准运算符为IS NOT DISTINCT FROM

OR的问题在于它无法使用索引。 ISNULL()的问题是相同的。因此,如果您的表有任何大小,则要避免使用它们。

您可以做的一件事就是将值设置为默认值。我不知道什么默认值会避免使用现有值,但这看起来像:

update table1
    set column1 = coalesce(column1, ''),  -- for strings
        column2 = coalesce(column2, -1),  -- for numbers
        column3 = coalesce(column3, cast('1900-01-01' as date))  -- for dates
    where column1 is null or column2 is null or column3 is null;

您需要在两个表上都执行此操作。然后,您可以在删除后恢复NULL值。

实际上,在SQL Server中,您可以添加计算列:

alter table1 add column1_notnull as (coalesce(column1, '')) persisted;  -- or whatever

然后您可以在它们上创建索引:

create index idx_table1_columns_123_notnull on table1(column1_notnull, column2_notnull, column3_notnull);

并重复table2

然后您的第一个查询将起作用(当然使用_notnull列)并利用索引来提高性能。

答案 2 :(得分:1)

可以尝试以下操作:

DELETE t1
FROM Table1 t1
JOIN Table2 t2
    ON 
    Isnull(t1.[Column1],'') = isnull(t2.[Column1],'')
    AND isnull(t1.[Column2],'') = isnull(t2.[Column2],'')
    AND isnull(t1.[Column3],'') = isnull(t2.[Column3],'');