所以我有3张桌子:
我想获取订购了 ItemID=2 的商品的客户的姓名,所以我使用了以下查询,当然它有效:
从 ClientID IN 的客户中选择客户名称(从 ItemID=2 的订单中选择 ClientID);
但是后来我发现另一个查询也运行得很好,如下查询:
从客户 WHERE 中选择客户名称(从订单中选择 ClientID WHERE Orders.ClientID=Clients.ClientID AND ItemID=2);
我完全可以理解第一个查询,但第二个查询对我来说似乎很模糊,特别是当它的子查询不能单独运行时。 为什么第二个中的“(SELECT ClientID FROM Orders WHERE Orders.ClientID=Clients.ClientID AND ItemID=2)”部分等于“ClientID IN (SELECT ClientID FROM Orders WHERE ItemID=2)” “从第一个开始就超出了我的理解。
谁能解释一下这是怎么回事?
SELECT Clientname
FROM Clients
Where ClientID IN (
SELECT ClientID
FROM Orders
WHERE ItemID=2
);
服务器执行子查询并获取
Orders.ClientID
值列表。然后,服务器测试每个 Clients.ClientID
值是否存在于上述列表中,并仅返回找到该值的那些行。
SELECT Clientname
FROM Clients
WHERE EXISTS (
SELECT ClientID
FROM Orders
WHERE Orders.ClientID=Clients.ClientID
AND ItemID=2
);
服务器针对每个
Clients.ClientID
值测试子查询描述的行是否存在。 IE。它将子查询中的 Clients.ClientID
替换为从某行获取的值,并查看匹配所有条件的行是否存在。
在前一个查询中,服务器必须收集值列表,然后通过它执行多次搜索。所以在大多数情况下这个查询很慢。
在后一个查询中,服务器测试每一行的新条件,但当找到至少一个匹配行时,它会停止搜索,并且不会测试到最后,它会开始搜索下一行。所以在大多数情况下这个查询应该更快。
在实践中,服务器应该解决我们的任务/查询,但同时它可以自由选择如何做。它足够智能,在大多数情况下,两个查询都将使用相同的执行计划(与后一个查询匹配)执行。特别是当表中存在合适的索引时。