【问题标题】:How do I replace EXISTS and NOT EXISTS with JOIN in SQL so I can translate it to relational algebra?如何在 SQL 中用 JOIN 替换 EXISTS 和 NOT EXISTS,以便将其转换为关系代数?
【发布时间】:2020-12-15 02:15:57
【问题描述】:

我想在以下查询中替换 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;

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

【问题讨论】:

  • 这些很容易找到常见问题解答。在考虑发布之前,请阅读手册和谷歌任何错误消息或您的问题/问题/目标的许多清晰、简洁和精确的措辞,有和没有您的特定字符串/名称和站点:stackoverflow.com 和标签;阅读许多答案。如果您发布问题,请使用一个短语作为标题。反映你的研究。请参阅How to Ask 和投票箭头鼠标悬停文本。

标签: mysql sql relational-algebra


【解决方案1】:

我建议使用LEFT JOININNER 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

【讨论】:

  • 这不等效,因为pokemon_name 可能在sinnohdex 中重复,这不会返回重复项。这可能是可取的行为,但这不是 OP 所要求的。
  • 那么 OP 也可以在 select 子句中使用 s.id。
【解决方案2】:

关闭,但不完全。我建议:

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 不会产生重复。

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

【讨论】:

  • RA 投影根据其定义返回唯一元组 (p 2.1.2),因此在不了解表结构的情况下,顶部查询中应该有 DISTINCT
  • @astentx 。 . .在外部查询中不需要SELECT DISTINCT——除非OP特别想删除sinnohdex中的重复项——这不是原始问题的一部分。由于子查询中的SELECT DISTINCTJOIN 不能产生重复的行。而LEFT JOIN 不能,因为它返回没有匹配的行。
  • 这是关于将查询转换为关系代数,根据 Codd 的文章,投影应该返回唯一的元组。我认为这是问题的重要组成部分(对准确性存在疑问)。子查询中的distinct呢:反正它的结果被过滤掉了,所以它也取决于数据。
猜你喜欢
  • 1970-01-01
  • 2017-01-08
  • 2018-01-13
  • 2015-02-20
  • 2013-11-18
  • 2014-12-29
  • 2023-03-08
  • 2021-08-29
  • 1970-01-01
相关资源
最近更新 更多