Mysql 使用无子查询重写包含两个子查询的查询
给定数据库架构:Mysql 使用无子查询重写包含两个子查询的查询,mysql,sql,Mysql,Sql,给定数据库架构: Part( PID, PName, Producer, Year, Price) Customer( CID, CName, Province) Supply(SID, PID, CID, Quantity, Amount, Date) 以及查询: Select cname, Province From Customer c Where exists ( Select * from Supply s join Part p on p.pId = s.
Part( PID, PName, Producer, Year, Price)
Customer( CID, CName, Province)
Supply(SID, PID, CID, Quantity, Amount, Date)
以及查询:
Select cname, Province
From Customer c
Where exists (
Select *
from Supply s
join Part p on p.pId = s.pId
Where CId = c.CId
and p.Producer = 'Apple'
)
and Not exists (
Select *
from Supply n
join Part nap on nap.pId = n.pId
Where CId = c.CId
and nap.Producer != 'Apple'
)
如果没有这两个子查询,我将如何重写这个查询 您想要只购买苹果产品的客户吗 一种可能的解决方案基于条件聚合:
Select c.cname, c.Province
From Customer c
join
( -- this is not a Subquery, it's a Derived Table
Select s.CId -- assuming there's a CId in Supply
from Supply s
join Part p
on p.pId = s.pId
group by s.CId
-- when there's any other supplier this will return 1
having max(case when p.Producer = 'Apple' then 0 else 1 end) = 0
) as p
on p.CId = c.CId
您可以使用
LEFT JOIN/NULL
模式查找尚未购买任何非苹果产品的客户。然后你就可以用连接来完成这一切。您必须加入供应
和零件
两次,一次用于查找苹果产品,另一次用于排除非苹果产品
SELECT distinct c.name, c.province
FROM Customer AS c
JOIN Supply AS s1 ON s1.cid = c.cid
JOIN Parts AS p1 ON p1.pid = s1.pid
LEFT JOIN Supply AS s2 ON s2.cid = c.cid
LEFT JOIN Parts AS p2 ON p2.pid = s2.pid AND p2.producer != 'Apple'
WHERE p1.producer = 'Apple' AND p2.pid IS NULL
注意,在
LEFT JOIN
中,您将第二个表的限制放在ON
子句中,而不是WHERE
子句中。有关此部分查询的更多信息,请参阅。我觉得您的查询很好。你为什么要重写它?