MySQL加入不存在的地方

gsu*_*008 68 mysql join not-exists

我有一个连接两个表的MySQL查询

  • 选民
  • 他们加入选民的家庭.household_id和household.id

    现在我需要做的是修改它,其中选民表连接到第三个名为elimination的表,沿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 
Run Code Online (Sandbox Code Playgroud)

Nic*_*oic 161

我可能会使用一个Left Join,即使没有匹配也会返回行,然后你可以通过检查NULL来只选择没有匹配的行.

所以,像:

SELECT V.*
FROM voter V LEFT JOIN elimination E ON V.id = E.voter_id
WHERE E.voter_id IS NULL
Run Code Online (Sandbox Code Playgroud)

是否比使用子查询更高效或更低效取决于优化,索引,是否可能每个选民有多个消除等等.

  • +1 在高负载时比子查询快得多 + 如果您可以执行 JOIN 而不是子查询 - 只需执行 JOIN,它们对于分析器来说就简单得多。另一个有用的例子,如果右表中有一些行或者没有行,你可能想要得到结果:`SELECT V.* FROM voter V LEFT JOIN消除 E ON V.id = E.voter_id OR E.voter_id IS NULL` 例如:如果您不想将所有记录存储在右侧表中左侧的每一行。 (3认同)

Dum*_*nka 8

有三种可能的方法来做到这一点。

  1. 选项

    SELECT  lt.* FROM    table_left lt
    LEFT JOIN
        table_right rt
    ON      rt.value = lt.value
    WHERE   rt.value IS NULL
    
    Run Code Online (Sandbox Code Playgroud)
  2. 选项

    SELECT  lt.* FROM    table_left lt
    WHERE   lt.value NOT IN
    (
    SELECT  value
    FROM    table_right rt
    )
    
    Run Code Online (Sandbox Code Playgroud)
  3. 选项

    SELECT  lt.* FROM    table_left lt
    WHERE   NOT EXISTS
    (
    SELECT  NULL
    FROM    table_right rt
    WHERE   rt.value = lt.value
    )
    
    Run Code Online (Sandbox Code Playgroud)


Ian*_*and 5

我会使用“不存在的地方”-正是您在标题中所建议的:

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
Run Code Online (Sandbox Code Playgroud)

这可能是稍快比做左连接(当然,这取决于您的索引,你的表的基数,等等),并且几乎可以肯定得多比使用更快。