SQL中的EXISTS子句和IN子句有什么区别?

什么时候应该使用EXISTS,什么时候应该使用IN?


当前回答

我假设您知道它们的作用,因此使用方式不同,所以我将把您的问题理解为:什么时候重写SQL以使用IN而不是EXISTS是一个好主意,或者反之亦然。

这个假设合理吗?


编辑:我问的原因是,在许多情况下,您可以重写基于in的SQL来使用EXISTS,反之亦然,对于某些数据库引擎,查询优化器将区别对待这两者。

例如:

SELECT *
FROM Customers
WHERE EXISTS (
    SELECT *
    FROM Orders
    WHERE Orders.CustomerID = Customers.ID
)

可以改写为:

SELECT *
FROM Customers
WHERE ID IN (
    SELECT CustomerID
    FROM Orders
)

或者用join:

SELECT Customers.*
FROM Customers
    INNER JOIN Orders ON Customers.ID = Orders.CustomerID

所以我的问题仍然存在,原来的海报想知道什么是IN和EXISTS,因此如何使用它,或者他问是否重写SQL使用IN使用EXISTS,反之亦然,将是一个好主意?

其他回答

我认为,

EXISTS是当您需要将查询结果与另一个子查询匹配时。 查询#1的结果需要在SubQuery结果匹配的地方检索。有点像Join.. 例如,选择表1中也下过表2订单的客户 IN用于检索特定列的值是否位于列表(1,2,3,4,5)中 例如,选择位于以下邮政编码中的客户,即zip_code值位于(....)列表中。

什么时候使用一种而不是另一种……当你觉得读起来合适的时候(更好地传达意图)。

如果使用IN操作符,SQL引擎将扫描从内部查询中获取的所有记录。另一方面,如果我们使用EXISTS, SQL引擎将在找到匹配项后立即停止扫描过程。

在某些情况下,使用In比使用EXISTS更好。通常,如果选择谓词在子查询中,则使用In。如果选择谓词在父查询中,则使用EXISTS。

https://docs.oracle.com/cd/B19306_01/server.102/b14211/sql_1016.htm#i28403

EXISTS将告诉您查询是否返回了任何结果。例如:

SELECT * 
FROM Orders o 
WHERE EXISTS (
    SELECT * 
    FROM Products p 
    WHERE p.ProductNumber = o.ProductNumber)

IN用于将一个值与多个值进行比较,并且可以使用文字值,如下所示:

SELECT * 
FROM Orders 
WHERE ProductNumber IN (1, 10, 100)

你也可以用IN子句来使用查询结果,就像这样:

SELECT * 
FROM Orders 
WHERE ProductNumber IN (
    SELECT ProductNumber 
    FROM Products 
    WHERE ProductInventoryQuantity > 0)

如果子查询返回多个值,则可能需要执行外层查询—如果条件中指定的列中的值与子查询结果集中的任何值匹配。要执行此任务,需要使用in关键字。

您可以使用子查询来检查一组记录是否存在。为此,您需要使用exists子查询子句。exists关键字总是返回true或false值。