2

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

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 评估在第二个查询(或第一个)中是如何工作的?查询的“解释”是什么?

Select *
From Customer c
Where Exists (True)
4

3 回答 3

3

前两个查询是不同的。

第一个有一个相关的子查询,将返回你想要的——关于有订单的客户的信息。

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

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

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

于 2013-05-14T15:14:56.663 回答
2

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

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

但是,您最有效的结果可能不是它们,而是:

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

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

您应该检查查询计划和/或对每个计划进行基准测试。

于 2013-05-14T15:13:14.603 回答
0

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

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

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

于 2013-05-14T15:14:03.807 回答