给定数据库架构:
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'
)
如果没有两个子查询,我将如何重写此查询?
答案 0 :(得分:0)
您想要只购买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
答案 1 :(得分:0)
您可以使用LEFT JOIN/NULL
模式查找尚未购买任何非Apple产品的客户。然后你可以通过连接完成所有这些操作。您必须两次加入Supply
和Parts
,一次用于查找Apple产品,然后再次排除非Apple产品。
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
子句。有关此部分查询的详情,请参阅Return row only if value doesn't exist。