Sql 从不存在转换为不存在

Sql 从不存在转换为不存在,sql,database,relational-database,relational-division,Sql,Database,Relational Database,Relational Division,我有三张桌子: 水手斯内姆,等级; 船名、颜色、等级; 预订sname、bname、工作日、开始、结束; 为了获得预订每艘红色船只的海员名单,我有: select s.sname from sailor s where not exists( select * from boat b where b.color = 'red' and not exists ( select * from reservation r w

我有三张桌子:

水手斯内姆,等级; 船名、颜色、等级; 预订sname、bname、工作日、开始、结束; 为了获得预订每艘红色船只的海员名单,我有:

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' )));
然而,这将返回一份所有预订了红船的水手的列表,不一定所有人都预订了红船。我很难检查列表中的名字是否已经预订了我也不能使用的每一艘船


任何帮助都将不胜感激,以便获得预订每艘船的水手名单。我将使用这个脚本

解决方案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));

这很有趣;您可以在替换不存在的子查询时维护相关子查询的语法结构。。。在…之前:


谢谢你的回复。不幸的是,我不得不使用嵌套的NOT INs,并且没有计数检查我的第二个解决方案不起作用。这将返回每个水手的列表。船的红色需要检查,但当我在交叉连接后添加检查时,它仍然不起作用。我已经更新了原始帖子。事实上,我正在寻找一份每一位预订过每一艘红船的水手的名单。很抱歉,你也不需要那种难看的字符串连接。其中a.sname不在,请选择r.sname FROM reservation作为r,其中r.sname不为NULL,r.bname=a.bname可以工作。您是否收到任何错误?没有SQL错误,但当我使用NOT INs运行第二个查询时,我会得到一个列表,其中列出了租用红色船只的每个海员,这与租用每艘船只的每个海员不同。对于这个问题,我很难将我的思想集中在不合逻辑的问题上。如果你想找到租了所有船只的水手,那么这种情况需要什么,其中b.color='red'很抱歉;我编辑了原稿。我正试图得到一份预订了每艘红船的水手名单,这是我的第一个查询所做的。。。建筑这是处理像您这样的关系划分问题的标准方法。在大多数情况下,它优于in…,因为它优雅地处理空值,并且不需要抑制重复项。13和42做什么?它们像临时变量吗?@user2619824:x不在SELECT x FROM中。。。表示与不存在相同的内容选择*从。。。。如果SELECT*FROM中有任何行。。。然后SELECT x返回一行x,否则不返回任何行。13和42可能都是1。值并不重要,因为我们只关心是否有值,即每个SELECT*中是否有一行。它们只是文字。子查询要么产生13,要么根本不产生任何结果。因此,如果我们将结果与13进行比较,我们要么得到真值,要么就没有什么可比较的了。这与not exixts几乎相同,它本身解析为布尔值。当然,42岁的孩子也是如此
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
       )
    );