在SQL中使用IN和EXISTS

时间:2013-05-14 15:08:38

标签: sql join relational-database

假设一个关系数据库中有三个表:

Customer(Id, Name, City),
Product(Id, Name, Price),
Orders(Cust_Id, Prod_Id, Date)

我的第一个问题是,优化查询的最佳方法是:“获取所有订购产品的客户”。 有些人建议使用EXISTS作为查询:

Select *
From Customer c
Where Exists (Select Cust_Id from Orders o where c.Id=o.cust_Id) 

以上查询是否等效(可写吗?)为:

 Select *
 From Customer
 Where Exists (select Cust_id from Orders o Join Customer c on c.Id=o.cust_Id)

除了效果之外我们使用IN代替EXISTS时会出现什么问题:

Select *
From Customer
Where Customer.Id IN (Select o.cust_Id from Order o )

上述三个查询是否返回完全相同的记录?

更新:EXISTS评估在第二个查询(或第一个)中的确如何工作,考虑到它只检查子查询是返回true还是false?查询的“解释”是什么?

Select *
From Customer c
Where Exists (True)

3 个答案:

答案 0 :(得分:3)

前两个查询不同。

第一个具有相关子查询,并将返回您想要的内容 - 有关订单的客户的信息。

第二个有一个不相关的子查询。它将返回所有客户或没有客户,具体取决于是否有客户下订单。

第三个查询是另一种表达你想要的方式。

cust_id可能具有NULL值时,我可以想到唯一可能出现的问题。在这种情况下,第一个和第三个查询可能不会返回相同的结果。

答案 1 :(得分:2)

是的,这三个中的每一个都应返回相同的结果集。 你的第二个查询不正确,正如@ypercube在表彰中指出的那样。您正在检查是否存在未校正的子查询EXISTS

在有效的两个(1,3)中,我希望#3是最快的,具体取决于你的表 ,因为它只执行一次子查询。

然而你最有效的结果可能没有,但是这个:

SELECT DISTINCT
    c.*
FROM
    Customer c
JOIN
    Orders o
    ON o.[cust_id] = c.[Id]

因为它应该只是一个索引扫描和一个哈希。

您应该检查每个查询计划和/或基准。

答案 2 :(得分:0)

执行该查询的最佳方法是将命令添加到from子句并加入它。

select distinct c.* 
from customers c, 
orders o
where c.id = o.cust_id

您的其他查询可能效率更低(取决于数据的形状),但它们都应返回相同的结果集。