Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在SQL中将NOT IN语句转换为NOT EXISTS语句?_Sql_Postgresql - Fatal编程技术网

如何在SQL中将NOT IN语句转换为NOT EXISTS语句?

如何在SQL中将NOT IN语句转换为NOT EXISTS语句?,sql,postgresql,Sql,Postgresql,我听说应该不惜一切代价避免不在中,因此我正在更新我的查询,以利用不存在并对它们运行解释分析,以查看是否有任何改进,但我很难对其进行认真思考。如何转换这样的查询: 选择id 来自客户c 其中c.状态不在 (“已删除”、“已存档”、“已过期”) 如果将not in与嵌套选择一起使用,则可能是正确的,例如: select id from customer c where c.status_id not in ( select id from status s where s.t

我听说应该不惜一切代价避免
不在
中,因此我正在更新我的查询,以利用
不存在
并对它们运行
解释分析
,以查看是否有任何改进,但我很难对其进行认真思考。如何转换这样的查询:

选择id
来自客户c
其中c.状态不在
(“已删除”、“已存档”、“已过期”)

如果将
not in
与嵌套选择一起使用,则可能是正确的,例如:

select id
from customer c
where c.status_id not in (
    select id
    from status s
    where s.type = 'DELETED'
)
这应该改写为:

select id
from customer c
where not exists(
    select *
    from status s
    where (s.id, s.type) = (c.status_id, 'DELETED')
)

但是,由于您正在使用带有一组可能值的
not in
,因此使用
exists

重写它是正常的,如果您使用嵌套选择的
not in
,则可能是正确的,例如:

select id
from customer c
where c.status_id not in (
    select id
    from status s
    where s.type = 'DELETED'
)
这应该改写为:

select id
from customer c
where not exists(
    select *
    from status s
    where (s.id, s.type) = (c.status_id, 'DELETED')
)
但是,由于您正在使用
not in
和一组可能的值,所以这没关系,而且使用
exists
重写它甚至很困难


我听说应该不惜一切代价避免
不在

你听错了——你在生产中应用了一些你不理解的东西(或者你在没有任何调查的情况下表面上接受的东西)。你所说的就是一个例子。不要这样做。不要相信没有引用和来源的任何东西(顺便说一句,这适用于生活中的一切)

无论如何,
不在
不存在
在语义上是不等价的:
中(和
不在
中)当与可变文字值或可变参数一起使用时,只是重复的
语句的语法糖,而
不存在
是对集合成员资格的测试,这是一个非常不同的操作

就您而言,这是:

WHERE c.status NOT IN ('DELETED', 'ARCHIVED', 'EXPIRED')
在语义上与此相同:

…这样一个表达式不能简化,我认为它是最优的

因此:不需要对此查询进行任何更改


我听说应该不惜一切代价避免
不在

你听错了——你在生产中应用了一些你不理解的东西(或者你在没有任何调查的情况下表面上接受的东西)。你所说的就是一个例子。不要这样做。不要相信没有引用和来源的任何东西(顺便说一句,这适用于生活中的一切)

无论如何,
不在
不存在
在语义上是不等价的:
中(和
不在
中)当与可变文字值或可变参数一起使用时,只是重复的
语句的语法糖,而
不存在
是对集合成员资格的测试,这是一个非常不同的操作

就您而言,这是:

WHERE c.status NOT IN ('DELETED', 'ARCHIVED', 'EXPIRED')
在语义上与此相同:

…这样一个表达式不能简化,我认为它是最优的


因此:不需要对此查询进行任何更改。

您不完全了解该规则。这是错误的:

我听说无论如何都应该避免不在

这更接近于事实:

我听说无论如何都应该避免不使用子查询

这有两个原因。到目前为止,更重要的是处理
NULL
值。如果子查询返回的任何值为
NULL
,则
notin
永远不会返回
TRUE
。也就是说,查询不返回任何行(如果这是唯一的条件)

另一方面,
notexists
实现了您在本例中所期望的功能,基本上忽略了子查询中的
NULL

这不是显式列表的问题,因为在显式列表中不太可能包含
NULL


第二个问题是性能。一些数据库将使用子查询优化
不存在
,比
不存在
要好得多——特别是在适当的索引可用的情况下。

您不完全了解规则。这是错误的:

我听说无论如何都应该避免不在

这更接近于事实:

我听说无论如何都应该避免不使用子查询

这有两个原因。到目前为止,更重要的是处理
NULL
值。如果子查询返回的任何值为
NULL
,则
notin
永远不会返回
TRUE
。也就是说,查询不返回任何行(如果这是唯一的条件)

另一方面,
notexists
实现了您在本例中所期望的功能,基本上忽略了子查询中的
NULL

这不是显式列表的问题,因为在显式列表中不太可能包含
NULL


第二个问题是性能。一些数据库将使用子查询优化
不存在
,这比
不在
中要好得多——特别是在适当的索引可用的情况下。

“我听说应该不惜一切代价避免
不在
中”-你从哪里听说的?我不同意那种说法。记住,所有的概括都是错误的,包括这个!“不惜一切代价”可能是言过其实,我应该更仔细地表达。这更像是一种“使用<代码>不在<代码>中时要小心”的建议,实际上,对于您来说,问题中提到的查询“不在”已经足够好了。当您在where子句中使用子查询来检查value@AkhileshMishra实际的查询在
语句中有一点拥挤,但我不想在不混淆所有内容的情况下发布原始查询,因此,我发布了一个简化版本。我不知道postgres的优化,但IME与其他产品的问题是
不在