SQL IN 工作但 NOT IN 不起作用
Posted
技术标签:
【中文标题】SQL IN 工作但 NOT IN 不起作用【英文标题】:SQL IN working but NOT IN does not work 【发布时间】:2013-03-13 18:18:45 【问题描述】:我有这个查询将正确返回属于IN
子句的值,但是当我将其更改为NOT IN
时,它不会返回任何内容。
有人有什么建议吗?
select distinct
CAST( w.work_area AS CHAR(4) ) || s.code_id as WATT
from
sys_code s,
work_area_master w
where
s.code_type = '590'
and (
CAST( w.work_area AS CHAR(4)) || s.code_id
)
in (
select substr(misc_flags, 1,6)
from sys_code where code_type = 'STA'
);
【问题讨论】:
提示:NULL 将使IN
的行为与您的预期不同。
NULL
s 正在弄乱您的结果,或者每一行都在该选择中
FROM sys_code s, work_area_master w
看起来不相关。 Mybe,您想在某个通用键域上加入它们吗?
【参考方案1】:
当 A 可能为 NULL 时,排除原则(即 A 或 ~A 是重言式)并不适用。当存在可空字段时,应用三值 loigc,并且必须将排除原则修改为( A 或 ~A 或 A 为 NULL)。
【讨论】:
【参考方案2】:SELECT DISTINCT
CAST( w.work_area AS CHAR(4) ) || s.code_id AS what
FROM sys_code s
JOIN work_area_master w ON 1=1
WHERE s.code_type = '590'
AND EXISTS (
SELECT * FROM sys_code xx
WHERE xx.code_type = 'STA'
AND substr(xx.misc_flags, 1,6) = CAST( w.work_area AS CHAR(4)) || s.code_id
);
脚注:我故意使用JOIN ... ON 1=1
语法来提醒大家注意原来的查询甚至没有连接条件(除了correlated IN 子查询中的那个)
【讨论】:
如果您要进行交叉连接,请使用 CROSS JOIN 语法编写一个。不要加入 1=1 为什么?这个更突出(我仍然不知道OP是否打算做一个carhesian产品,除了子查询)EXISTS
>> IN
。我冒昧地把它变成了一个合适的CROSS JOIN
- 我希望你没问题。
我讨厌语法糖。对我来说1=1
比所有的模糊词更容易阅读。
抱歉打扰了,如果您不同意,请回滚更改。不过,我确实认为使用正确的CROSS JOIN
会更好。【参考方案3】:
检查sys_code
和work_area_master
的组合是否有效实际上可以是JOIN
条件。
同时使用EXISTS
而不是IN
来避免NULL
出现问题,例如@wilplasser already provided:
SELECT DISTINCT
CAST( w.work_area AS CHAR(4) ) || s.code_id AS what
FROM sys_code s
JOIN work_area_master w ON EXISTS (
SELECT 1
FROM sys_code x
WHERE x.code_type = 'STA'
AND substr(x.misc_flags, 1,6)
= CAST(w.work_area AS CHAR(4)) || s.code_id
)
WHERE s.code_type = '590' ;
有关NOT IN
和NULL
问题的详细说明,请参阅此closely related question on dba.SE。
【讨论】:
【参考方案4】:可以包含这样的合并函数:
select distinct CAST( w.work_area AS CHAR(4) ) || s.code_id as WATT
from sys_code s, work_area_master w
where s.code_type = '590'
and (CAST( w.work_area AS CHAR(4)) || s.code_id) in (
select substr(coalesce(misc_flags," "), 1,6)
from sys_code
where code_type = 'STA'
);
【讨论】:
不鼓励使用隐式连接的 SQL 反模式。在这种情况下,他似乎有一个交叉连接,这可能是也可能不是他想要的,下一个维护它的人不会知道这是一个错误还是故意的。如果以后的更改添加了额外的 code_type,这尤其危险。 我同意 HLGEM 的观点。但是,如果这是程序员的故意,一些交叉连接可以完全实现。这就是为什么我坚信最好的做法之一是对代码进行评论,而不是让其他人了解作者创建此类代码的意图。 如果您使用显式连接,则只有编写一个交叉连接才能使用。这就是为什么隐式连接是一个非常糟糕的主意的原因之一,如果你打算这样做,因为你的意图不明确。即使您发表评论,cmets 也经常过时,以至于许多开发人员不会意识到它仍然是相关的。如果你使用代码,意图总是很明确的。 出色的 HLGEM!感谢您指出这一点。我会期待自己的代码来避免这样的陷阱。以上是关于SQL IN 工作但 NOT IN 不起作用的主要内容,如果未能解决你的问题,请参考以下文章