0

我正在尝试查看 t1 中的记录,其中来自 t1 的源 ID 不在 t2 中。

就像......“其他表中不存在哪些记录?”

我需要在 FROM 子句中包含 t2 吗?谢谢

SELECT t1.fee_source_id, t1.company_name, t1.document
FROM t1
WHERE t1.fee_source_id NOT IN (

     SELECT t1.fee_source_id
     FROM t1 INNER JOIN t2 ON t1.fee_source_id = t2.fee_source

                              )
ORDER BY t1.aif_id DESC 
4

2 回答 2

1

您正在寻求实现反连接,在 MySQL 中有三种可能性:

  1. 使用IN

    SELECT fee_source_id, company_name, document
    FROM   t1
    WHERE  fee_source_id NOT IN (SELECT fee_source FROM t2)
    ORDER BY aif_id DESC
    
  2. 使用EXISTS

    SELECT fee_source_id, company_name, document
    FROM   t1
    WHERE  NOT EXISTS (
      SELECT * FROM t2 WHERE t2.fee_source = t1.fee_source_id LIMIT 1
    )
    ORDER BY aif_id DESC
    
  3. 使用JOIN

    SELECT   t1.fee_source_id, t1.company_name, t1.document
    FROM     t1 LEFT JOIN t2 ON t2.fee_source = t1.fee_source_id
    WHERE    t2.fee_source IS NULL
    ORDER BY t1.aif_id DESC
    

根据@Quassnoi 的分析

概括

MySQL 可以优化所有三种方法来完成一种NESTED LOOPS ANTI JOIN.

它将从 中获取每个值t_left并在索引中查找它t_right.value。在索引命中或索引未命中的情况下,相应的谓词将立即分别返回FALSEor TRUE,并且将立即做出是否返回行的决定,t_left而无需检查 中的其他行t_right

但是,这三种方法会生成三种不同的计划,由三段不同的代码执行。执行谓词的代码比执行和优化使用方法的代码效率低EXISTS30% 。index_subqueryLEFT JOINNot exists

这就是为什么在MySQL中搜索缺失值的最佳方法是使用LEFT JOIN / IS NULLorNOT IN而不是NOT EXISTS.

但是,我不完全确定该分析如何与 MySQL 手册中关于Optimizing Subqueries with EXISTSStrategy的部分相一致,这表明上面的第二种方法应该比第一种更有效。

于 2012-12-23T19:22:19.220 回答
0

下面的另一个选项(类似于反加入)......虽然上面的答案很好。谢谢!

 SELECT   D1.deptno, D1.dname
        FROM     dept D1
        MINUS
        SELECT   D2.deptno, D2.dname
        FROM     dept D2, emp E2
        WHERE    D2.deptno = E2.deptno
        ORDER BY 1;
于 2012-12-23T19:37:16.737 回答