代码之家  ›  专栏  ›  技术社区  ›  webworm

SQL联接匹配空列值

  •  0
  • webworm  · 技术社区  · 6 年前

    我用的是 JOIN 在MS SQL Server 2012中,使用

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

    但是,如果两个表中的列都包含 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 回复  |  直到 6 年前
        1
  •  1
  •   Ankur Patel    6 年前

    可以尝试以下操作:

    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],'');
    
        2
  •  3
  •   Gordon Linoff    6 年前

    这是一个真正的问题,因为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;
    

    你需要在两张桌子上都这样做。然后你可以恢复 无效的 删除后的值。

    实际上,在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 当然是列)并使用索引来提高性能。

        3
  •  3
  •   Mureinik    6 年前

    你可以用 SET ANSI_NULLS OFF 使 = 请客 null 是一样的。