2014-06-16 64 views
0

我有一個SQL查詢,像這樣:MySQL必須匹配兩個表中的兩列......否則返回空結果?

SELECT t1.key, t1.value 
FROM table1 AS t1, table2 AS t2 
WHERE t1.pID IN (45, 67, 88, 32) AND t2.id = t1.id; 

這似乎返回所有行t1.pId IN (45, 67, 88, 32),但它不應該因爲t2.id應進一步降低該行的結果,但似乎並不像它正在這樣做。

我需要減少通過t2.id返回的行,但是如果在通過t1.pId值數組排序後找不到t2.id,它應該返回一個空結果。

EDITED 表,試圖選擇t1列,不t2,對不起。但是隻有滿足這兩個條件,並且只有在第二個條件爲真後才返回結果行。此外,現在修復表格,以便它是正確的。

+1

如果你加入2個表之間的公用密鑰的數據是什麼? –

+0

2之間沒有共同的關鍵...對不起 –

+0

't2.id = t1.pID'暗示這是兩個表之間的公共關鍵。 –

回答

0

我不確定連接表的逗號語法是否會導致MySQL執行某些您不期望的操作,但是如果您重寫了它以使用明確的JOIN,那麼我認爲您會發現它更清晰你的條件是和JOIN如何發生。這裏的建議是:

SELECT t2.key, t2.value 
FROM table1 AS t1 
LEFT OUTER JOIN table2 AS t2 ON t1.id = t2.id 
WHERE t1.id IN (45, 67, 88, 32) 
     AND t2.id IS NOT NULL 

這裏的想法是,你明確地加入了表t2,並聲明它應該如何連接。

然後,通過刪除t2.id中NULL的所有行,將行減少到僅成功連接的行。 t2.id將爲空如果沒有匹配的t2行,當加入t1.id = t2.id

+0

已更新的問題,對不起,不完全正確...請看看。謝謝:) –

+0

我不知道我是否理解你的編輯,但它看起來像你只是改變了一些列名和/或想選擇不同的列。我更新了SQL以反映我注意到的更改,但這只是更改列名稱的問題。同樣的技術應該仍然有效。 – Josh

1

您的查詢返回符合指定條件的每一行。也就是說,它只檢查單個行是否滿足謂詞,並返回所做的行,而不管沒有行的行。

如果我明白你在問什麼(我不完全確定我是這麼做的),你說你想在某些行滿足t1.id上的謂詞時返回一個「空集」,但至少有一個在t2中沒有匹配行的t1中的行。

要檢查是否有行沒有在T2「匹配」,我們可以使用反連接模式(還有其他的方法,以及...

SELECT SUM(1) AS t1_rows_not_matched 
    FROM table1 t1 
    LEFT 
    JOIN table2 t2 
    ON t2.id = t1.id 
WHERE t1.pID IN (45, 67, 88, 32) 
    AND t2.id IS NULL 

去拿到納入您查詢時,您可以使用,作爲一個內嵌視圖,包括謂詞來檢查不匹配的行數,例如:

SELECT d.key 
    , d.value 
    FROM (SELECT SUM(1) AS cnt_rows_not_matched 
      FROM table1 t1 
      LEFT 
      JOIN table2 t2 
      ON t2.id = t1.id 
      WHERE t1.pID IN (45, 67, 88, 32) 
      AND t2.id IS NULL 
     ) c 
CROSS 
    JOIN table1 d 
WHERE d.pID IN (45, 67, 88, 32) 
    AND c.cnt_rows_not_matched = 0 

這可能不是回答你問的問題,但它不是清楚你在問什麼。


每行都單獨檢查。如果滿足謂詞,它將被返回。只有在沒有匹配的行時,您發佈的查詢纔會返回空集。

您可能希望檢查是否至少有一行匹配列表中包含的每個pID值。也就是說,例如,如果沒有行的pID值爲32,那麼您希望查詢返回一個空集,而不是符合條件的行集。

SELECT d.key 
    , d.value 
    FROM (SELECT SUM(1) AS cnt_rows_not_matched 
      FROM table1 t1 
      LEFT 
      JOIN table2 t2 
      ON t2.id = t1.id 
      WHERE t1.pID IN (45, 67, 88, 32) 
      AND t2.id IS NULL 
     ) c 
CROSS 
    JOIN (SELECT COUNT(DISTINCT f.pID) AS cnt_pid 
      FROM table1 f 
      WHERE f.pID IN (45, 67, 88, 32) 
     ) p 
CROSS 
    JOIN table1 d 
WHERE d.pID IN (45, 67, 88, 32) 
    AND c.cnt_rows_not_matched = 0 
    AND p.cnt_pid = 4 

+0

我想返回符合'WHERE'語句的所有行。否則,不要返回它們,而是返回一個空的結果。這有助於更清楚嗎?並且謝謝btw。 –

+0

再次感謝,但我不認爲你在這裏跟着我。我只想返回兩個WHERE條件都爲真的行......就像我通常在table2上做一個INNER JOIN一樣,如果table2的ON語句不是真的,它應該去掉左表值。這正是我想要做的,但不要認爲'INNER JOIN'會在這裏工作......除非我錯了? –

+0

聲明中只有一個WHERE子句,而不是兩個。 WHERE子句中有兩個_predicates_。布爾AND運算符指定一行必須滿足_both_謂詞才能返回。這就是你原來的陳述所做的。使用內部連接,謂詞是出現在WHERE子句還是ON子句中並不重要。 (老式的逗號連接操作符,就像在你的查詢中一樣,是一個連接操作,缺少示例數據和期望的結果(以及與你發佈的查詢的輸出有什麼不同,我無法幫到你) – spencer7593

相關問題