SQL NOT IN 仍包含应排除的行

Posted

技术标签:

【中文标题】SQL NOT IN 仍包含应排除的行【英文标题】:SQL NOT IN still includes rows that should be excluded 【发布时间】: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 的测试。但它正在查询中返回,这是我不想要的。

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

我犯了语法错误吗?

【问题讨论】:

括号可能更容易调试... 【参考方案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))

【讨论】:

以上是关于SQL NOT IN 仍包含应排除的行的主要内容,如果未能解决你的问题,请参考以下文章

sql 2008 r2 在sql 2008上兼容么

SQL基础

有大神知道,sql server 中如何批量执行sql语句吗?

pl sql developer怎么执行sql

pl sql developer怎么执行sql

sql SQL Server和Oracle SQL的SQL语法的一些示例