我有三张桌子:
sailor
(sname,rating); boat
(bname,颜色,评级); reservation
(sname,bname,weekday,start,finish); 为了获得保留每艘红船的水手名单,我有:
select s.sname from sailor s
where not exists(
select * from boat b
where b.color = 'red'
and not exists (
select * from reservation r
where r.bname = b.bname
and r.sname = s.sname));
我现在需要使用NOT IN而不是NOT EXISTS重写此查询。这就是我到目前为止所拥有的:
select s.sname from sailor s
where s.sname not in (select s2.sname from sailor s2 where
s2.sname not in (select r.sname from reservation r where r.bname not in (
select b.bname from boat b where b.color <> 'red' )));
然而,这会返回所有保留红船(不一定都是全部)的水手的清单。我很难检查列表中的名字是否保留了每条船(我也不能使用COUNT())。
感谢任何帮助
答案 0 :(得分:4)
这很有趣;您可以在NOT EXISTS ( ... )
替换IN ( ...)
的同时维护句法结构(相关子查询):
SELECT s.sname from sailor s
WHERE 13 NOT IN (
SELECT 13 FROM boat b
WHERE b.color = 'red'
AND 42 NOT IN (
SELECT 42 from reservation r
WHERE r.bname = b.bname
AND r.sname = s.sname
)
);
答案 1 :(得分:0)
为了获得保留每艘船的水手名单。我将使用此脚本
解决方案1:
;WITH k AS
(
SELECT b.sname,COUNT(distinct a.bname) coun FROM boat a
INNER JOIN reservation b
on a.bname = b.bname
GROUP BY b.sname
)
SELECT k.sname FROM k WHERE coun = (select COUNT(*) FROM boat AS b)
解决方案2:
SELECT s.sname
FROM sailor AS s
WHERE s.sname NOT IN (SELECT DISTINCT a.sname
FROM (SELECT s.sname,
b.bname
FROM sailor AS s
CROSS JOIN boat AS b
WHERE b.color = "Red") a
WHERE a.sname + a.bname
NOT IN (SELECT r.sname + r.bname
FROM reservation AS r
WHERE r.sname IS NOT NULL
AND r.bname IS NOT NULL));