2014-09-26 94 views
0

我試圖運行一個查詢,查詢存在於子查詢中的表中的所有記錄。MySQL WHERE EXISTS評估爲真所有記錄

但是,它正在返回所期望的所有記錄。

下面是該查詢:

SELECT DISTINCT x FROM T1 WHERE EXISTS 
     (SELECT * FROM T1 NATURAL JOIN T2 WHERE T2.y >= 3.0); 

我試圖測試子查詢和返回的滿足我的約束記錄正確的號碼。

但是,當我運行整個查詢時,它會返回應該不存在於子查詢中的記錄。

爲什麼EXISTS對T1中的所有記錄都評估爲真?

回答

2

您需要關聯的子查詢,而不是子查詢中的連接。目前還不清楚正確的關聯條款是什麼,但是像這樣:

SELECT DISTINCT x 
FROM T1 
WHERE EXISTS (SELECT 1 FROM T2 WHERE T2.COL = T1.COL AND T2.y >= 3.0); 

您的查詢有一個常規的子查詢。每當它返回至少一行時,則exists爲真。所以,必須至少有一個匹配的行。此版本「邏輯上」運行外部T1中每行的子查詢。

+0

這工作!謝謝,我會盡快接受這個答案。我確實對關聯vs連接有一些困惑。爲什麼大腦的表現總是這樣呢? – jor 2014-09-26 02:47:16

+0

你的行爲始終如一,因爲第二個查詢是完全獨立的,因此表中的每個記錄都存在被評估表中的每個記錄。即沒有辦法將子查詢結果與T1中的任何特定行對齊,因此所有行都被返回。 – 2014-09-26 03:00:14

1

問:爲什麼EXISTS對T1中的所有記錄都評估爲真?

答:因爲子查詢返回一行,完全獨立於外部查詢中的任何內容。

EXISTS謂詞只是檢查子查詢是否正在返回一行,並返回布爾值TRUE或FALSE。

你會得到同樣的結果:

SELECT DISTINCT x FROM T1 WHERE EXISTS (SELECT 1) 

(唯一的區別是,如果子查詢沒有返回至少一行,那麼你會得到沒有行外部查詢返回)

子查詢返回的行與外部查詢中的行之間沒有關聯。


我希望還有另一個問題要問。而這個答案真的取決於你想要返回的結果集。

如果你想返回從T1是在T2一些「匹配」行的行,你可以使用一個NOT EXISTS (correlated subquery)

或者,你也可以使用一個連接操作返回同樣的結果,例如:

SELECT DISTINCT T1.x 
    FROM T1 
NATURAL 
    JOIN T2 
    WHERE T2.y >= 3.0 
+0

謝謝!是的,看到上面的例子後,我對EXISTS的工作原理有了更好的理解。在添加外部和內部查詢之間的關聯後,我獲得了正確的結果! – jor 2014-09-26 02:52:21

+0

@JulioReyes:我會給出一個關聯的子查詢的例子,但是'NATURAL JOIN'實際上是「隱藏」你在'T1'和'T2'中匹配的列的名字。我的個人偏好是避免使用NATURAL JOIN,因爲如果它在T1包含列'(fa,fee,fi,fo,fum)'且T2包含列'(doh,ray,me,fa)時它正在「工作」 '...將另一列添加到T1或T2,使用與另一個表中現有列的名稱匹配的名稱將「斷開」查詢。例如,向T1添加'me'列會改變NATURAL JOIN操作的功能。 – spencer7593 2014-09-26 02:59:47

+0

此外,與NATURAL JOIN一起,爲了「弄清楚」哪些列正在「匹配」,讀者需要比較T1和T2的定義,以找到所有具有相同名稱的列。 (我更喜歡編寫我的查詢,這樣如果有人向表中添加一列,並且不會讓閱讀器查閱表定義以找出正在引用的列名稱,它們就不會「破壞」。 – spencer7593 2014-09-26 03:04:52

0

它不工作,因爲外部查詢和正在使用的子查詢之間沒有關聯。下面存在的and T1.id = T2.id

SELECT DISTINCT x 
FROM T1 
WHERE EXISTS (SELECT 1 FROM T2 WHERE T2.y >= 3.0 and T1.id = T2.id) 
; 

形式的相關性但不知道我會希望你不需要在查詢中使用「不同」的數據,這會產生相同的結果:

SELECT x 
FROM T1 
WHERE EXISTS (SELECT 1 FROM T2 WHERE T2.y >= 3.0 and T1.id = T2.id) 
; 

的替代,這可能會需要不同的,是OFH你的第二個查詢下半年

SELECT DISTINCT x FROM T1 NATURAL JOIN T2 WHERE T2.y >= 3.0 
+0

感謝,現在更有意義!我沒有做任何關聯。 – jor 2014-09-26 02:50:52

0

您可以使用INNER JOIN的變化來得到你」重新嘗試去:

SELECT DISTINCT T1.X 
    FROM T1 
    INNER JOIN T2 
    ON T2.COL = T1.COL 
    WHERE T2.Y > 3.0 

分享和享受。