【问题标题】:Can you use multiple columns for a not in query?您可以使用多列来进行非查询吗?
【发布时间】:2010-02-12 14:55:57
【问题描述】:

我最近看到有人将此作为 SO 查询问题答案的一部分发布:

SELECT DISTINCT a, b, c 
FROM t1 
WHERE (a,b,c) NOT IN 
   ( SELECT DISTINCT a,b,c FROM t2 )

我有点困惑,因为我一直认为您不能将多个列用于“NOT IN”(“where(a,b,c)”等)。这是正确的 SQL 语法吗?那么 MySQL 呢?

【问题讨论】:

    标签: sql mysql syntax


    【解决方案1】:

    谷歌搜索表明它适用于某些数据库,但不适用于其他数据库。你可以改用这个:

    SELECT DISTINCT a, b, c 
    FROM t1 
    WHERE NOT EXISTS
       (SELECT 1 FROM t2 
        WHERE t1.a = t2.a AND t1.b = t2.b AND t1.c = t2.c)
    

    【讨论】:

      【解决方案2】:

      这是一个 SQL 扩展。 Oracle、PostgreSQL 和 MySQL 都有。 SQL Server 2005 没有它。我不确定其他人。

      【讨论】:

        【解决方案3】:

        它确实在 Oracle 中工作。快速设计的例子:

        SQL> select ename, job, deptno from emp
          2  where (ename, deptno) in
          3  ( select ename, deptno from emp
          4    where job = 'MANAGER'
          5  );
        
        ENAME      JOB           DEPTNO
        ---------- --------- ----------
        JONES      MANAGER           20
        CLARK      MANAGER           10
        PARAG      MANAGER           30
        

        这也有效:

        SQL> select ename, job, deptno from emp
          2  where (ename, deptno) in (('JONES',20),('CLARK',10));
        
        ENAME      JOB           DEPTNO
        ---------- --------- ----------
        JONES      MANAGER           20
        CLARK      MANAGER           10
        

        也没有:

        SQL> select ename, job, deptno from emp
          2  where (ename, deptno) not in
          3  ( select ename, deptno from emp
          4    where job = 'MANAGER'
          5  );
        
        ENAME      JOB           DEPTNO
        ---------- --------- ----------
        SMITH      CLEANER           99
        SCOTT      ANALYST           20
        KING       PRESIDENT         10
        FORD       ANALYST           20
        MILLER     CLERK             10
        

        【讨论】:

        • 他在问'NOT IN'。不只是'IN'
        • @David Oneill - 你不能假设如果一个有效,那么另一个也有效?
        • 添加 NOT IN 示例只是为了确定!
        • @froadie,不,你不能假设。或者至少,我不会。
        【解决方案4】:

        我不知道,但如果你是字符类型(或者可以转换为字符类型),你可以伪造它:

        SELECT DISTINCT a, b, c  
        FROM t1  
        WHERE a+b+c NOT IN  
           ( SELECT DISTINCT a+b+c FROM t2 ) 
        

        【讨论】:

        • 这有一个错误。 a='ab' b='cd' c='ef' 将匹配 a='abcd' b='e' c='f'...
        • 您需要小心确保不会因列内容而发生冲突。我会放入分隔符,这样列就不会意外运行在一起导致误报:'a' + 'bb' + 'c" == 'ab' + 'b' + 'c'
        • 不适用于某些字符串... a+b 可以是 a="ab" 和 b="c" 的 "abc",或者 a="a" 和 b="公元前”。
        • 是的,是的,是的......我正要提到这一点,但由于它只是一个黑客,我选择了快速解决方案。
        • 您可以在这些字段之间添加那些字段中不存在的分隔符。我建议使用 CHAR(0),并注意空值:SELECT DISTINCT a, b, c FROM t1 WHERE a+CHAR(0)+b+CHAR(0)+c NOT IN (SELECT DISTINCT a+CHAR(0) +b+CHAR(0)+c FROM t2 )
        【解决方案5】:

        试试这个

        SELECT DISTINCT a, b, c  
        FROM t1,
        (SELECT DISTINCT a,b,c FROM t2) as tt
        WHERE t1.a NOT IN tt.a
        AND t1.b NOT IN tt.b
        AND t1.c NOT IN tt.c
        

        注意:这还没有经过测试,甚至还没有被证明是正确的。

        【讨论】:

        • 我的问题不是如何去做——我知道几种方法。我只是想知道语法是否正确,因为有人发布了它并且没有人反对。
        • @froadie 请原谅我的误解。我看到其他人已经正确回答了您的问题。
        【解决方案6】:

        其他人已经回答了这个问题,但作为性能建议,如果您要处理任何重要大小的数据,请始终使用 EXISTS 语句而不是 IN。几乎在所有情况下都会更快。

        http://decipherinfosys.wordpress.com/2007/01/21/32/

        【讨论】:

          猜你喜欢
          • 2021-12-09
          • 2011-12-05
          • 1970-01-01
          • 2010-10-31
          • 2014-02-03
          • 1970-01-01
          • 1970-01-01
          • 2021-12-31
          • 1970-01-01
          相关资源
          最近更新 更多