2011-02-16 27 views
1

以下兩個查詢是否總是給出相同的結果?如果不是,爲什麼不呢?SQL查詢 - 存在與否的區別

1)

select PayFrequencyTypeID, PayFrequencyDesc 
from db_uspaybo.tblpayfrequency 
where (PayFrequencyTypeID,1) not in (
    select payfrequencytype,1 
    from tblcustomerpayapproval 
    where fedtaxid='903008887' and payrollyear=year(curdate()) 
); 

2)

select payfrequencytypeid 
from tblpayfrequency 
where not exists (
    select distinct payfrequencytype 
    from tblcustomerpayapproval 
); 

預先感謝。

+0

你有沒有試過運行它來看看自己? – 2011-02-16 12:14:01

+0

他們爲什麼會這樣?第一個有一個WHERE條件,它不會在第二個任何地方出現,也可以選擇一個額外的列。 – 2011-02-16 12:14:41

+1

@Sachin - 這個愚蠢是關於性能的,這是關於語義的。鏈接問題中的答案沒有提及具有NULL的`NOT IN`將返回一個空的結果集。 – 2011-02-16 12:20:17

回答

2

我認爲這是你想要的'不存在' A.Id和B.Id這裏是連接這些表的Pk和FK。(我不知道確切的字段名)

從tblpayfrequency一個 其中不存在選擇payfrequencytypeid(從tblcustomerpayapproval B,其中A.Id = B.Id和B.fedtaxid = '903008887' 和B選擇*
.payrollyear =年(CURDATE()));

1

基本上not innot exists非常相似,通常會得到相同的結果。

區別在於,如果集合中的某個值爲NULL(至少在Oracle上),則in將返回false,而exists僅檢查記錄的存在,忽略其值。

在這種特定情況下,您得到了一個WHERE子句,它將導致第一個查詢返回不同的結果。

第三種方法一般要快於MySQL的,是左連接表中主查詢,並檢查連接字段爲空:

select payfrequencytypeid 
from 
    tblpayfrequency f 
    left join tblcustomerpayapproval a 
    on a.payfrequencytype = f.payfrequencytype 
where 
    a.payfrequencytype IS NULL 

其他一般提示:

  1. 當然你可以跳過1
  2. 第二個查詢中不需要DISTINCT。如果刪除該數據庫,則允許數據庫選擇最佳優化路徑。
  3. 雖然這也取決於數據庫選擇的優化路徑,但不存在通常更快。你應該真的在實時服務器上嘗試這一點,並確保實時數據。
1

簡體和標記:

SELECT p, d 
FROM f 
WHERE (p, 1) NOT IN 
    (SELECT t, 1 
    FROM a 
    WHERE i='903008887' 
    AND y = year (curdate())); 


SELECT p 
FROM f 
WHERE NOT EXISTS 
    (SELECT DISTINCT t 
    FROM a); 

結果會不一樣。原因:第一個查詢要求輸入2列。但是我們無法知道該年的問題是否會產生某些影響,或者是否爲903008887過濾。如果該過濾有效 - 第二個查詢怎麼辦?

1

第一個從db_uspaybo.tblpayfrequency返回其PayFrequencyTypeID不在payfrequencytype表中的一些數據與這些條件。

第二個不會從db_uspaybo.tblpayfrequency返回任何數據。