2013-06-27 51 views
6

我有一個表是外部id和本地id之間的映射。任何或如果存在T-SQL

我不得不寫一個查詢來確定這個表是否是雙射。我想出了這個

IF 1 <> ANY(
    SELECT COUNT(foreignId) 
    FROM mappingTable 
    GROUP BY localId 
    ) 
BEGIN 
    SELECT 'Oh noes!' 
END 

ELSE BEGIN 
    SELECT 'Everything is fine.' 
END 

我的導師看了一眼這一點,做了個鬼臉,並告訴我,我應該寫這個:

IF EXISTS(
    SELECT NULL 
    FROM mappingTable 
    GROUP BY localId 
    HAVING COUNT(foreignId) <> 1 
    ) 
BEGIN 
    SELECT 'Oh noes!' 
END 

ELSE BEGIN 
    SELECT 'Everything is fine.' 
END 

我的問題很簡單這些疑問的是更好的風格。我很確定它們是相同的。

+0

爲什麼上不了檯面採用了獨特的約束:無指標

enter image description here

查詢計劃?像UNIQUE(localId,foreignId)一樣,每個映射只能被抹黑一次。該檢查由數據庫引擎完成,您不必編寫任何代碼。 –

+0

@ JennyO'Reilly我試圖檢查從外部收到的數據的完整性。 –

+0

然後先創建表和約束,然後嘗試插入數據。如果數據不正確,您的數據庫系統應該會報錯。 :-) –

回答

8

在SQL Server 2008上進行測試表明,這些查詢不僅可以提供相同的結果,而且它們甚至具有相同的查詢計劃。查詢優化器已經知道這些查詢是等價的。因此,任何有利於彼此的論證都必須關注諸如風格等其他方面。

就我個人而言,第二個查詢更容易理解,即使第一個查詢更接近於如何用英語表示搜索,因爲我已經看到EXISTS遠遠超過ANY。第一個查詢讓我去「等等,什麼?哦,是的,沒錯......」第二個問題對我來說很明顯。對其他人可能不同(也許對你而言);你應該儘量確保你的主管和同事的查詢很容易閱讀。

2

根據您的專欄是否有索引,您的查詢同樣不好或同樣好。

如果沒有索引,將會有一個表掃描/聚簇索引掃描所有行,然後是哈希匹配,刪除重複項。

如果您在檢查的列上有索引,則兩個查詢都將使用該索引,並在發現重複時提前終止。

查詢計劃與指數:

enter image description here