2012-03-09 113 views
1

我有一個SQL不是很複雜,但充分混淆,我質疑,而我有一個等值或重合計數是相同的。如何擺脫不存在

SQL1:

SELECT a, b 
FROM table1 
WHERE NOT EXISTS(
    SELECT a, c 
    FROM TABLE2 
    WHERE table2.a != table1.a) 

SQL2

SELECT table1.a, table1.b 
FROM table1 
LEFT JOIN table2 ON table2.a = table1.a 
WHERE table2.a IS NULL 

上兩者是相同的,但不知道這是一個偶然的機會,我想,以確保轉換不改變計數原創功能。

+0

不知道我得到了SQL1的功能。你想從table1中得到a,b,其中a是table2.a的唯一值? – 2012-03-09 15:40:48

+0

我認爲重點是從table1中獲取表2中沒有相應條目的行。 – Dave 2012-03-09 15:45:10

+0

@Dave是的,我認爲這是最初的預期目的。但我不是100%肯定的,我正試圖優化它,以便它運行得更快。 – Churk 2012-03-09 16:12:56

回答

2

的第一個查詢,你有它返回TABLE1的所有行,其中a與TABLE2中的a的所有值匹配。因此,它將返回零行,,除非TABLE2中存在a的單個非空值,並且該值存在於TABLE1中。在這種情況下,它將返回TABLE1中的行數爲a

第二個查詢是完全不同的。它將簡單地返回TABLE1的所有行,其中a在TABLE2中不存在。

所以它的 「比賽所有」(查詢1)對 「不匹配任何」(查詢2)。你得到相同數量的行的事實純屬巧合。如果你在第一個爲=改變!=,這樣

你的查詢是等價的:

SELECT a, b 
FROM table1 
WHERE NOT EXISTS(
    SELECT a, c 
    FROM TABLE2 
    WHERE table2.a = table1.a) 

,讓你的a值中不存在表2表1。這是完全一樣的:

SELECT table1.a, b 
FROM table1 
LEFT JOIN table2 ON table2.a = table1.a 
WHERE table2.a IS NULL 

當你擁有了它,雖然,他們是不等價的。您必須在第一個變更!==才能完成。

+0

第一個查詢不能改變,這是我從轉換。所以在排序上,這兩個查詢是不相同的,只是巧合的是,計數返回相同。 – Churk 2012-03-09 15:56:32

+1

第一個查詢不是有效的語法(提示:EXIST),第二個查詢也不是第二個(提示:'SELECT'子句中的'a'不明確),它們也不相同! – onedaywhen 2012-03-09 16:05:57

+0

@onedaywhen我基本上不得不重新鍵入查詢,所以請原諒拼寫錯誤。但那不是我遇到的問題,也不是這個問題。 – Churk 2012-03-09 16:14:22

3

這看起來不一樣 - 但它很接近。您的LEFT JOIN語法與以下內容相同:

SELECT a, b 
FROM table1 
WHERE NOT EXIST(
    SELECT a, c 
    FROM TABLE2 
    WHERE table2.a = table1.a) 

注意「=」而不是「!=」。你確定這不是你所擁有的?

實際查詢轉換爲類似「在沒有非匹配的行存在」,這將是奇怪的,但可以通過改變聯接條件表示:

SELECT a, b 
FROM table1 
LEFT JOIN table2 ON table2.a != table1.a 
WHERE table2.a IS NULL 
+0

第一個sql是我所擁有的,第二個sql是我可以改變的。所以你說的是連接條件,我應該在連接列上使用!=,但是這不會導致另一個問題本身? – Churk 2012-03-09 15:57:54

+0

@Churk:我看到的唯一問題是它會讓人困惑 - 但不如原始查詢。這是一個奇怪的條件,檢查,並不符合(至少我的)標準設置思維 - 但如果你是100%正面,這是你的,我會去與左加入和大量的爲什麼類型的評論。 – 2012-03-09 18:27:48

1
SELECT a, b, c , d 
FROM table1 t1 
WHERE NOT EXISTS(SELECT * FROM table2 nx 
    WHERE nx.y = t1.a 
) 
    ; 

有這樣一個很大的優勢(「相關子查詢」)方法:表表2是無法從外部查詢可見,不能污染,或混淆你的思維。子查詢只產生一點信息:它存在或不存在。 是或不是...
在這方面,LEFT JOIN成語很難理解,因爲您必須在外部查詢中檢查xxx IS NULL條件,而xxx從內部查詢引用table2。

從技術上講,沒有區別。

2

對於第一查詢即

SELECT a, b 
FROM table1 
WHERE NOT EXISTS(
    SELECT a, c 
    FROM TABLE2 
    WHERE table2.a != table1.a) 

這將返回所有行時atable1的所有值都相同的一個值,並且無論是在table2所有行是相同的一個值作爲table1table2是空集。否則,結果將是空集。

相同不能與您的第二個查詢相同。

+0

謝謝你進一步解釋,我可以看到你現在的意思。 – Churk 2012-03-09 16:44:45