2009-04-15 60 views
46

我有一個MySQL查詢聯接兩個表MySQL的加入凡NOT EXISTS

  • 選民
  • 家庭 他們加入對voters.household_id和household.id

    現在我需要做的是將選民表加入到名爲淘汰的第三個表中,沿voter.id和elimination.voter_id進行修改,我想排除選民表中有任何記錄在淘汰中的記錄表。我如何製作一個查詢來做到這一點?

這是我當前的查詢

SELECT `voter`.`ID`, `voter`.`Last_Name`, `voter`.`First_Name`, 
     `voter`.`Middle_Name`, `voter`.`Age`, `voter`.`Sex`, 
     `voter`.`Party`, `voter`.`Demo`, `voter`.`PV`, 
     `household`.`Address`, `household`.`City`, `household`.`Zip` 
FROM (`voter`) 
JOIN `household` ON `voter`.`House_ID`=`household`.`id` 
WHERE `CT` = '5' 
AND `Precnum` = 'CTY3' 
AND `Last_Name` LIKE '%Cumbee%' 
AND `First_Name` LIKE '%John%' 
ORDER BY `Last_Name` ASC 
LIMIT 30 

回答

122

我可能會使用一個左連接,這將返回行,即使沒有比賽,然後你可以不匹配由只選擇行檢查NULL。

所以,像這樣:

SELECT V.* 
FROM voter V LEFT JOIN elimination E ON V.id = E.voter_id 
WHERE E.voter_id IS NULL 

這是否是比使用子查詢或多或少的效率取決於優化,索引,它可能是否讓每個選民多於一個的消除等

+8

+1返回比子查詢更快 – ravi404 2012-11-16 15:07:49

+1

+1在高負載和子查詢時+1快得多+如果U可以做JOIN而不是子查詢 - 只要JOIN對於分析器來說簡單得多。 另一個有用的例子是,如果在右表中有一些行或者沒有人,U可能想要得到結果:`SELECT V. * FROM voter V LEFT JOIN elimination E ON V.id = E.voter_id OR E .voter_id IS NULL`例如:如果U不想將右側表中的所有記錄存儲在左側的每一行中。 – 2016-07-04 05:45:50

4

我會用一個「其中不存在」 - 正是因爲你在你的標題提示:

SELECT `voter`.`ID`, `voter`.`Last_Name`, `voter`.`First_Name`, 
     `voter`.`Middle_Name`, `voter`.`Age`, `voter`.`Sex`, 
     `voter`.`Party`, `voter`.`Demo`, `voter`.`PV`, 
     `household`.`Address`, `household`.`City`, `household`.`Zip` 
FROM (`voter`) 
JOIN `household` ON `voter`.`House_ID`=`household`.`id` 
WHERE `CT` = '5' 
AND `Precnum` = 'CTY3' 
AND `Last_Name` LIKE '%Cumbee%' 
AND `First_Name` LIKE '%John%' 

AND NOT EXISTS (
    SELECT * FROM `elimination` 
    WHERE `elimination`.`voter_id` = `voter`.`ID` 
) 

ORDER BY `Last_Name` ASC 
LIMIT 30 

這可能是稍快比做左連接(當然,這取決於你的索引,你的表的基數等),並且幾乎肯定是比使用IN更快得多

+0

謝謝你 - 對我來說肯定是更快。 – spidie 2013-05-20 05:47:30

1

有三種可能的方式來做到這一點。

  1. 選項
 
     SELECT lt.* FROM table_left l 
     LEFT JOIN 
      table_right r 
     ON  rt.value = lt.value 
     WHERE rt.value IS NULL 
  • 選項
  •  
         SELECT lt.* FROM table_left l 
         WHERE lt.value NOT IN 
         (
         SELECT value 
         FROM table_right r 
         ) 
    
  • 選項
  •  
         SELECT lt.* FROM table_left l 
         WHERE NOT EXISTS 
         (
         SELECT NULL 
         FROM table_right r 
         WHERE rt.value = lt.value 
         )