Mysql 如何用SQL中的联接替换EXISTS和notexists,以便将其转换为关系代数?

Mysql 如何用SQL中的联接替换EXISTS和notexists,以便将其转换为关系代数?,mysql,sql,relational-algebra,Mysql,Sql,Relational Algebra,我要替换以下查询中的EXISTS和NOT EXISTS: SELECT pokemon_name FROM sinnohdex s WHERE NOT EXISTS (SELECT * FROM hoenndex h WHERE s.id = h.id) AND EXISTS (SELECT * FROM johtodex j WHERE j.id = s.id); 到目前为止,我得到的是: SELECT pokemon_name FROM sinnohde

我要替换以下查询中的EXISTS和NOT EXISTS:

SELECT pokemon_name FROM sinnohdex s
WHERE NOT EXISTS
    (SELECT * FROM hoenndex h
     WHERE s.id = h.id)
AND EXISTS
    (SELECT * FROM johtodex j
     WHERE j.id = s.id);
到目前为止,我得到的是:

SELECT pokemon_name FROM sinnohdex s
LEFT JOIN hoenndex h ON s.id = h.id
INNER JOIN johtodex j ON j.id = s.id
WHERE h.id IS NULL;

我的目标是以后将查询“翻译”成关系代数。
我甚至不知道这是否准确。
我的想法是只使用连接编写查询
这是对的吗?

很接近,但不完全正确。我建议:

SELECT s.pokemon_name
FROM sinnohdex s JOIN
     (SELECT DISTINCT j.id
      FROM johtodex j
     ) j
     ON j.id = s.id LEFT JOIN
     hoenndex h
     ON s.id = h.id
WHERE h.id IS NULL;
子查询中需要
SELECT DISTINCT
,以确保
JOIN
不会重复产品


加入前删除重复项通常比加入后删除重复项更有效(尽管这可能取决于数据)。

我建议使用
左加入
内部加入
,如下所示:

SELECT distinct pokemon_name 
  FROM sinnohdex s JOIN johtodex j ON j.id = s.id
  LEFT JOIN hoenndex h ON s.id = h.id
 WHERE h.id is null

这些是很容易找到的常见问题。在考虑发帖之前,请阅读本手册,谷歌搜索任何错误信息,或您的问题/问题/目标的许多清晰、简洁和准确的措辞,包括或不包括您的特定字符串/名称和网站:stackoverflow.com&tags;阅读许多答案。如果你发布一个问题,用一句话作为标题。反思你的研究。请参阅投票箭头mouseover texts.RA投影根据其定义(p)返回唯一元组(&S),因此在不了解表结构的情况下,顶部查询中应该有
DISTINCT
。@astentx。在外部查询中不需要
SELECT DISTINCT
,除非OP特别希望删除
sinnohdex
中的重复项,这不是原始问题的一部分。由于子查询中的
SELECT DISTINCT
JOIN
无法生成重复行。而
左连接不能,因为它返回的行没有匹配项。它是关于将查询转换为关系代数的,根据Codd的文章,投影应该返回唯一的元组。我认为这是问题的关键部分(对准确性有怀疑)。子查询中的
distinct
如何:它的结果无论如何都会被过滤掉,因此它也取决于数据。这是不等价的,因为
pokemon_name
可能在
sinnohdex
中重复,并且不会返回重复的结果。这可能是理想的行为,但不是OP所要求的。那么OP也可以在select子句中使用s.id。