UPDATE 中令人讨厌的 WHERE 子句

Obnoxious WHERE Clause in UPDATE

我在 UPDATE 语句中发现了以下 WHERE 子句,我讨厌它。我认为让它与众不同的唯一方法可能是 CTE 和一些工会。

FROM dbo.Table1 T1      
INNER JOIN #Table2 T2 ON T1.IntField1 = T2.IntField1
WHERE (ISNULL(T1.IntField2, 0) <> ISNULL(T2.IntField2, 0)
    OR ISNULL(T1.IntField3, 0) <> ISNULL(T2.IntField3, 0))
    AND (T2.IntField1 IN (
        SELECT IntField1
        FROM dbo.Table3)
        OR T2.IntField1 IS NULL)

我想我盯着这个看得太久了。我只是碰巧看了这个SP,看到了这个。真的觉得可以做点什么differently/better。

它不是最漂亮的,但除非它表现不佳,否则没有必要更改它。永远不要仅仅因为您不喜欢它的外观就更改 SQL 代码,这通常会适得其反,因为一些外观最差的代码是性能最高的,DBA 不会感谢您更改他们调整后的代码.认为您应该更改 SQL 代码以适应您的个人喜好是您需要改掉的坏习惯。请阅读有关性能调优的内容,并通过重构来提高性能,而不是迎合您对漂亮或(更糟糕的优雅!)代码的偏见。

不过,我看到有两件事可能对此有所帮助。首先,为什么需要 OR T2.IntField1 IS NULL?由于您在该字段上加入到 table1 的内部联接,因此永远不会有 T2.IntField1 为 NULL 的结果集。

另一件事取决于#table2 的用途。但是,由于您显然是在早些时候创建和填充此 table,为什么不将 T2.IntField2 和 T2.IntField3 转换为 0,因为它们在数据放入 table 时为空?那会降低一些更新查询的复杂度。但是,如果您在此过程中出于其他目的需要这些空值,则无法执行此操作。

看来您可以将 where 子句的元素组合成联接:

概览:

1) NOT (A AND B) 等同于 NOT(A) OR NOT(B)

2) IN OR NULL 可以在 ISNULL() 连接中组合。

FROM dbo.Table1 T1      
    JOIN #Table2 T2 ON T1.IntField1 = T2.IntField1
        AND NOT 
        (
             ISNULL(T1.IntField2, 0) = ISNULL(T2.IntField2, 0)
             and 
             ISNULL(T1.IntField3, 0) = ISNULL(T2.IntField3, 0)
        )
    JOIN dbo.Table3 t3 on 
         t3.IntField1 = ISNULL(T2.IntField1, t3.IntField1)

但如前所述,如果性能是唯一的关注点,那么这个——尽管更具可读性(在我看来)——就没有必要了。