2015-02-06 31 views
0

我在UPDATE語句中找到了下面的WHERE子句,我討厭它。我認爲唯一能讓它與衆不同的方法是與CTE和一些聯盟。更新中令人討厭的WHERE子句

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,看到這個。真的覺得有些事情可以做得不同/更好。

回答

1

這不是最漂亮的不,但並不需要改變它,除非它表現糟糕。不要因爲你不喜歡它的外觀而改變SQL代碼,這往往會適得其反,因爲一些最糟糕的代碼是最高性能的代碼,DBA不會感謝你改變他們的調整代碼。認爲你應該改變SQL代碼以適合你的個人偏好是你需要打破的壞習慣。請閱讀有關性能調整的內容,然後重構以提高性能,以便不符合您對漂亮或(更加優雅!)代碼的偏見。

有兩件事我可以看到,但可能會有所幫助。首先,你爲什麼需要OR T2.IntField1 IS NULL?由於您正在加入對該字段的table1的內連接,因此永遠不會有T2.IntField1爲NULL的結果集。

另一件事取決於#table2用於什麼。但是,由於您明確地創建並填充了此表,爲什麼不在將數據放入表時將T2.IntField2和T2.IntField3轉換爲0時爲空?這會降低更新查詢的複雜度。但是,如果您在此過程中需要這些空值作爲其他用途,則無法執行此操作。

0

看起來你可以結合where子句的元素融入加入:

概述:

1)NOT(A和B)相同,NOT(A)OR NOT(B)

2)IN或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) 

但正如之前所說,如果性能是唯一的重點,這雖然更可讀(在我看來)是沒有必要的。