查找通过住在纽约的所有供货商订过货的客户,在关系模型中很容易写出,因为关系模型中提供了除法,但在sql语句利用关键词很难写,不妨先从数理的角度理解一下。
在关系模型中 A ∩ B = A - (A - B),在这个题目中是货单和纽约市的所有供货商做一个交运算,即货单集合 - (货单集合 - 供货商集合),这里的减和原来关系模型的减不一样。
考虑反向,即存在纽约市的供货商没有给特定的客户c提供货物,
a.city = 'New York' and not exists(
Select * from Customers c, Orders o
Where c.cid = o.cid and c.aid = o.aid
)
这样继续取反不存在纽约市的供货商给特定的客户c提供货物,也即所有的纽约市的供货商都向特定的客户c提供货物。
not exists(
a.city = 'New York' and not exists
(Select * from Customers C, Orders O
Where c.cid = o.cid and c.aid = o.aid
)
)
sql语句如下:
Select c.cid from Customers C where
not exists (
Select * from Agents a where a.city = 'New York'
and not exists(
Select * from Orders o where o.cid = a.cid
and o.aid = a.aid
)
);
当然看到这些心情可能会有些复杂,所以做个题吧:
求出住在New York 或 Duluth并订购了价值超过一美元的所有商品的代理商的aid
从简单的开始
Select a.aid from Agents a where a.city = 'New York' or a.city = 'Duluth';
代理商确定
确定是“所有超过一美元的商品”,限定条件写一级not exists,
Select a.aid from Agents a where
a.city = 'New York' or a.city = 'Duluth' and not exists(
Select pid from Products p where p.price > 1 )
最后写有代理商没有订购
Select a.aid from Agents a where
a.city = 'New York' or a.city = 'Duluth' and not exists(
Select pid from Products p where p.price > 1 and not exists(
Select * from Orders o where o.pid = p.pid and
o.aid = a.aid
)
);