【问题标题】:SQL NOT IN still includes rows that should be excludedSQL NOT IN 仍包含应排除的行
【发布时间】:2013-10-21 13:16:50
【问题描述】:

我有以下语句来查找包含某些值但排除其他值的行:

SELECT * 
FROM tests 
WHERE author = 4  
OR id = -999 
OR id = 276 
OR id = 343 
OR id = 197 
OR id = 170 
OR id = 1058 
OR id = 1328 
OR id = 1417 
AND is_deleted = 0 
AND id NOT IN (457, 2409, 173, 400, 167, 277, 163, 404, 2222, 24, 26, 
               2457, 16, 25, 1639, 2224, 1804, 2308, 197, 461, 1442, 
               1594, 460, 1235, 1814, 2467, 168, 172, 170, 171, 2223, 2535, 2754)

但是,根据 NOT IN 列表,我仍然得到应该排除的行。例如,即使 tests.author = 4,也应排除 id 为 16 的测试。但它正在查询中返回,这是我不想要的。

语句是根据情况以编程方式创建的。

我犯了语法错误吗?

【问题讨论】:

  • 括号可能更容易调试...

标签: mysql sql notin


【解决方案1】:

看看SQL Server's operator precedence。您会看到and 的优先级高于or

假设您正在寻找一辆红色或蓝色的快速汽车。如果你写:

where speed = 'fast' and color = 'green' or color = 'blue'

SQL Server 将读取:

where (speed = 'fast' and color = 'green') or color = 'blue'

为了响应您的查询,SQL Server 可能会返回一辆缓慢的蓝色汽车。

【讨论】:

    【解决方案2】:

    将您的查询更改为:

    SELECT * 
    FROM tests 
    WHERE (author = 4  OR id = -999 OR id = 276 OR id = 343 OR id = 197 OR id = 170 OR id = 1058 OR id = 1328 OR id = 1417) 
          AND is_deleted = 0
          AND id NOT IN (457, 2409, 173, 400, 167, 277, 163, 404, 2222, 24, 26, 2457, 16, 25, 1639, 2224, 1804, 2308, 197, 461, 1442, 1594, 460, 1235, 1814, 2467, 168, 172, 170, 171, 2223, 2535, 2754)
    

    你必须把你所有的or 放在括号里。

    【讨论】:

      【解决方案3】:

      试试这个::

      SELECT 
      * 
      FROM tests 
      WHERE 
      (author = 4  
      OR 
      id in (-999,276 ,343 ,197 ,170 ,1058 ,1328 ,1417) 
      AND is_deleted = 0 )
      AND id NOT IN (457, 2409, 173, 400, 167, 277, 163, 404, 2222, 24, 26, 2457, 16, 25, 1639, 2224, 1804, 2308, 197, 461, 1442, 1594, 460, 1235, 1814, 2467, 168, 172, 170, 171, 2223, 2535, 2754)
      

      【讨论】:

        【解决方案4】:

        Omair,您放错了“(”,首先要明确您要选择哪个作者。
        假设我们需要,
        author = 4 或 id 包含在 -999、343、197 等中且已删除状态 = 0 且 ID 不得在 457、2409、......等中的作者。
        你所做的是,

        作者 = 4 或 id = -999 或 id = 276 ...
        AND is_deleted = 0
        并且 id 不在 (457, 2409, 173, 400, 167, 277, 163, 404, 2222, 24, 26, ...)

        这根据operator precedence解释为

        (作者 = 4) 或 (id = -999 或 id = 276 ...
        AND is_deleted = 0
        并且 id 不在 (457, 2409, 173, 400, 167, 277, 163, 404, 2222, 24, 26, ...)
        )

        在这里,我们只需要添加适当的 '(' 来分隔我们需要的条件

        ((作者 = 4 ) OR ( id = -999 OR id = 276 ...)
        AND (is_deleted = 0)
        和 (id 不在 (457, 2409, 173, 400, 167, 277, 163, 404, 2222, 24, 26, ...) ) )

        所以你可以用适当的括号来改变 SQL,

        选择 * 来自测试
        在哪里
        ((作者 = 4)或 ID 在 (-999,276 ,343 ,197 ,170 ,1058 ,1328 ,1417))
        AND (is_deleted = 0)
        AND ( id 不在 (457, 2409, 173, 400, 167, 277, 163, 404, 2222, 24, 26, 2457, 16, 25, 1639, 2224, 1804, 2308, 197, 461, 1442, 1594, 460、1235、1814、2467、168、172、170、171、2223、2535、2754))

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-05-11
          • 1970-01-01
          • 2019-11-21
          • 1970-01-01
          相关资源
          最近更新 更多