2017-07-25 135 views
0

我有兩個字段,其中#data表中的電子郵件地址正在嘗試加入。我希望它加入代表電子郵件地址,如果這不起作用,我希望它加入電子郵件。我試着運行下面的查詢:更有效的寫查詢方式

select a.* 
from #data a 
join #email b on b.email=coalesce(a.rep_email_address,a.email) 
where a.rep_email_address<>a.email 

然而,這並不工作,因爲在a.rep_email_adress不爲空,但不b.email匹配的情況下,將丟棄記錄,而不是採取a.email字段。

這是變通,我發現:

select a.* 
from #data a 
join #email b on a.email=b.email 
except 
select a.* 
from #data a 
join #email b on a.rep_email_address=b.email 
union 
select a.* 
from #data a 
join #email b on a.rep_email_address=b.email 
where a.rep_email_address<>a.email 

然而,這是很不理想的,所以我wondering-任何方式來寫這個有更好的表現/看起來更乾淨或更簡單?爲了澄清這個查詢的工作原理(第二個查詢),我想知道是否有更好的方法來編寫它。

謝謝!

+0

您需要澄清問題是否在列爲null或者在兩種情況下都可以填充它們,並且您想要加入。 – scsimon

+0

我說這個問題不是說a.rep_email_adress是null(它不是) - 但只是與b.email不匹配;然而,a.email字段確實如此,所以如果rep_email_address沒有加入(不是因爲它是空的,而是根本沒有加入),我想要加入郵件字段。 – edost4

+0

嗯,喲在這種情況下說,但這並不明確,它可能是和/或不能爲null,但謝謝澄清 – scsimon

回答

3

這應該是簡單得多。但是,我還建議您檢查此查詢的執行計劃,以幫助您分析這是否更優化。 [或者只是比較所產生的執行時間上的表格]

SELECT a.* 
    FROM #data a 
     JOIN #email b 
      ON (a.rep_email_address = b.email 
       OR a.email = b.email) 
WHERE a.rep_email_address<>a.email; 
# Not sure why or IF you need this where clause specifically. 
+0

信不信由你,在第一個rep_email_address匹配的情況下,這會導致重複,然後郵件匹配。雖然我的查詢不是 – edost4

+0

你介意分享這3種情況的預期輸出 - (i)其中只有rep_email_address與b.email相匹配(ii)只有a.email與b.email匹配且(iii)其中a.rep_email_address和a.email是相同的,他們匹配b.email? – DeadLock

+2

將不同添加到選擇。您不會因爲使用union all而受到重複@ edost4 – scsimon

1

嘗試像這樣...

SELECT 
    a.*, 
    SomeColumn = ISNULL(e1.SomeColumn, e2.SomeColumn) 
from 
    #data a 
LEFT JOIN #email e1 
    ON e1.email = a.rep_email_address 
LEFT JOIN #email e2 
    ON e2.email = a.email 
    AND e1.email IS NULL 
WHERE 
    a.rep_email_address <> a.email 
    AND (
      e1.email IS NOT NULL 
      OR 
      e2.email IS NOT NULL 
     ); 

HTH,傑森

+0

謝謝你也工作! – edost4

1

SQL服務器在布爾評估採用「Three-Valued Logic」:

  • NULL <> 2 - >未知(在WHERE子句就會在你的情況基本上成爲假)
  • NULL <> NULL - >未知(同上)
  • a <> b - >真

在你的情況你的原始查詢應該是:

select a.* 
from #data a 
join #email b on b.email=coalesce(a.rep_email_address,a.email) 
where ISNULL(a.rep_email_address, '') <> ISNULL(a.email, '') 

如果你關心性能,則儘量避免使用在連接謂詞函數或WHERE條件,因爲這可以防止SQL Server使用的列的索引是被傳入該函數。

SELECT a.* 
FROM #data AS a 
    INNER JOIN #email AS b ON b.email = a.rep_email_address OR b.email = a.email 
WHERE a.rep_email_address <> a.email OR (a.rep_email_address IS NULL OR a.email IS NULL) 

摘要:

不要使用NULL s到表示空字符串,因爲這需要大量的額外代碼,然後檢查NULL小號

+0

該查詢的結果與DeadLock's即ie相同。它重複了一些記錄。雖然我的查詢不是 – edost4

+0

這意味着您在#email表中有多個匹配的記錄。正如@scsimon所提到的那樣,你的貓嘗試不同的 – Alex

+0

謝謝Alex! – edost4