I have three tables:
sailor
(sname, rating); boat
(bname, color, rating); reservation
(sname, bname, weekday, start, finish);In order to get a list of sailors who have reserved every red boat, I have:
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));
I now need to rewrite this query with NOT IN instead of NOT EXISTS. Here's what I have so far:
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' )));
This, however, returns a list of all sailors who have reserved a red boat (not necessarily all of them). I'm having great difficulty checking whether or not a name in the list has reserved EVERY boat (I also cannot use COUNT()).
Any help is appreciated
Inorder to get a list of sailors who have reserved every boat. I'll use this script
Solution 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)
Solution 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));