2009-04-15 62 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 
         )