【问题标题】:Select from a table the ones that don't have a relationship with another table从一个表中选择与另一个表没有关系的表
【发布时间】:2015-01-02 06:03:52
【问题描述】:

具体问题是列出从未评分的老师的名字。

我有一个包含“姓名”和“ID”列的“教师”表。
以及带有 'IDTeacher' 和 'Grade' 列的 'grades' 表。

不明白为什么这不起作用:

Select Name from teachers where not exists(Select * from grades, teachers)

【问题讨论】:

  • SELECT * WHERE NOT EXISTS的可能重复
  • Dognose 和 Gordon Linoff 都有正确的做法。您不起作用的原因是您的内部选择没有任何标准可以将其与外部选择匹配,并且您正在其中进行隐含的完全外部连接,因此除非您不这样做,否则内部选择将始终返回行'在年级和教师中都没有任何行。

标签: mysql


【解决方案1】:

您可以将其与成绩表连接起来,并使用连接返回“null”的右侧:

SELECT
   name
from
   teachers t
LEFT JOIN
   grades g
on
   t.teacher = g.teacher
WHERE
   ISNULL(g.teacher)

edit:考虑了一个右连接,但是不,如果教师在成绩表中没有no条目,右连接可能不起作用。 (那么你会完全想念他,即使他在teacher 表中)

您也可以为此使用WHERE IN

SELECT 
  name 
FROM 
  teachers 
WHERE 
  name 
NOT IN (SELECT name from grades)

但是 MySQL 优化器会将其重写为与 @Gordon Linoff 编写的完全相关的子查询。使用WHERE NOT IN 更容易阅读恕我直言。

【讨论】:

  • 也许我看这张图的次数超出了我的预期。 stackoverflow.com/a/16598900/3403036:D
  • 你知道不存在我该如何解决吗?谢谢它的作品
  • @AntonioCraveiro 请参阅 Gordon Linoffs 的答案以获取解决方案 not exists
【解决方案2】:

您的查询确实工作,它只是没有按照您的想法进行。子查询在两个表之间创建一个笛卡尔积。如果两个表都有行,那么笛卡尔积也有行,where 子句将始终为真。

您可以采用这种方法,但需要关联子查询:

Select Name
from teachers t
where not exists (Select 1 from grades g where g.idteacherid = t.id);

请注意,此查询在子查询中只有一个表。

还有其他方法可以编写此查询,但这似乎是您要采用的方法。而且,not exists 是一种非常合理的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-30
    相关资源
    最近更新 更多