首页 文章

从一个表中选择不在另一个表中

提问于
浏览
49

我试图找到一个表而不是另一个表中的行,两个表都在不同的数据库中,并且在我用来匹配的列上也有不同的列名 .

我有一个查询,下面的代码,我认为它可能有效,但它太慢了:

SELECT `pm`.`id`
FROM `R2R`.`partmaster` `pm`
WHERE NOT EXISTS (
    SELECT * 
    FROM `wpsapi4`.`product_details` `pd`
    WHERE `pm`.`id` = `pd`.`part_num`
)

所以查询尝试执行如下操作:

从R2R.partmaster数据库中选择不在wpsapi4.product_details数据库中的所有ID . 我匹配的列是partmaster.id和product_details.part_num

4 回答

  • 55

    扩展Sjoerd的反连接,您还可以使用易于理解的 SELECT WHERE X NOT IN (SELECT) 模式 .

    SELECT pm.id FROM r2r.partmaster pm
    WHERE pm.id NOT IN (SELECT pd.part_num FROM wpsapi4.product_details pd)
    

    请注意,您只需要对保留字,带空格的名称等使用 ``` 反引号,而不是使用普通列名 .

    在MySQL 5上,这种查询运行得非常快 .
    在MySQL 3/4上它很慢 .

    Make sure you have indexes on the fields in question
    你需要在 pm.idpd.part_num 上有一个索引 .

  • 2

    你可以LEFT JOIN这两个表 . 如果第二个表中没有对应的行,则值将为NULL .

    SELECT id FROM partmaster LEFT JOIN product_details ON (...) WHERE product_details.part_num IS NULL
    
  • 78

    因此网上有大量帖子展示了如何做到这一点,我发现了3种方式,与Johan和Sjoerd指出的相同 . 我无法让任何这些查询工作,显然它们工作正常,这是我的数据库无法正常工作,这些查询都运行缓慢 .

    所以我找到了其他人可能会觉得有用的另一种方式:

    它的基本要点是创建一个临时表并用所有信息填充它,然后删除另一个表中的所有行 .

    所以我做了这3个查询,并且运行得很快(在几分钟内) .

    CREATE TEMPORARY TABLE
    
    `database1`.`newRows`
    
    SELECT
    
    `t1`.`id` AS `columnID`
    
    FROM
    
    `database2`.`table` AS `t1`
    

    .

    CREATE INDEX `columnID` ON `database1`.`newRows`(`columnID`)
    

    .

    DELETE FROM `database1`.`newRows`
    
    WHERE
    
    EXISTS(
        SELECT `columnID` FROM `database1`.`product_details` WHERE `columnID`=`database1`.`newRows`.`columnID`
    )
    
  • 3

    要扩展Johan的答案,如果子选择中的part_num列可以包含空值,那么查询将会中断 .

    要更正此问题,请添加空检查...

    SELECT pm.id FROM r2r.partmaster pm
    WHERE pm.id NOT IN 
          (SELECT pd.part_num FROM wpsapi4.product_details pd 
                      and pd.part_num is not null)
    
    • 抱歉,但我不能拥有代表!

相关问题