【问题标题】:SQL query find records that not persists in other tablesSQL查询查找不存在于其他表中的记录
【发布时间】:2018-07-13 20:28:54
【问题描述】:

我需要打印所有非学生和教师的人。我有三张桌子。甲骨文数据库。到目前为止的代码:

SELECT PersonID, FirstName, LastName, Gender, DateOfBirth
FROM PERSON 
INNER JOIN STUDENT S ON PERSON.PersonID = S.StudentID 
INNER JOIN TEACHER T ON PERSON.PersonID = T.TeacherID
WHERE PERSON.PersonID != S.StudentID
AND PERSON.PersonID != T.TeacherID;

我猜我的查询是错误的,因为它返回 0 个结果。你知道我必须改变什么吗?

【问题讨论】:

    标签: sql database oracle oracle11g qsqlquery


    【解决方案1】:

    使用not exists:

    select p.*
    from person p
    where not exists (select 1 from teacher t where t.teacherid = p.personid) and
          not exists (select 1 from students s where s.studentid = p.personid);
    

    虽然你可以用left join写这个查询,但我认为使用not exists的版本几乎是问题的直接翻译,更容易理解。

    在 Oracle 中,您也可以使用 minus 编写此代码——如果您只需要 id:

    select personid
    from person
    minus
    select teacherid
    from teacher
    minus
    select studentid
    from student;
    

    【讨论】:

    • 1 代表什么?
    • @TeodorKolev 。 . . exists 和 not exists 仅检查是否返回了 row,而不检查列的内容。 1 是定义列的最简单方法。
    • 我对这两个答案都投了赞成票,但@APC 的答案似乎更合适(选择一个)
    【解决方案2】:

    "我的查询是错误的,因为它返回 0 个结果"

    当有匹配时,内连接返回记录。您正在尝试查找既不加入 STUDENT 也不加入 TEACHER 的 PERSON 记录。因此,将您的查询更改为使用外连接:

    SELECT PersonID, FirstName, LastName, Gender, DateOfBirth
    FROM PERSON 
    LEFT OUTER JOIN STUDENT S ON PERSON.PersonID = S.StudentID 
    LEFT OUTER JOIN TEACHER T ON PERSON.PersonID = T.TeacherID
    WHERE S.StudentID is null
    AND  T.TeacherID is null;
    

    这是一个反连接:它从 PERSON 返回与 STUDENT 和 TEACHER 中的记录不匹配的记录。

    【讨论】:

    • ORA-00933: SQL 命令未正确结束 00933. 00000 - “SQL 命令未正确结束”
    【解决方案3】:

    --用左外连接试试这个...

    SELECT
      P.PersonID, 
      P.FirstName, 
      P.LastName, 
      P.Gender, 
      P.DateOfBirth
    FROM PERSON P
    LEFT OUTER JOIN STUDENT S ON P.PersonID = S.StudentID 
    LEFT OUTER JOIN TEACHER T ON P.PersonID = T.TeacherID
    WHERE S.PersonID is null and T.PersonID is null
    

    【讨论】:

    • 这似乎与我半小时前发布的答案非常相似,并且 OP 认为该答案是正确的。
    • 哈哈,我是堆栈溢出的第一个计时器...我无法正确格式化它。
    • 现在你知道如何格式化一个答案,你可以学习如何删除一个:) 说真的,有很多问题没有任何答案,为什么不解决其中的一些呢?重复的答案只会使线程变得混乱,并且作为未来寻求者的资源不太有用。
    猜你喜欢
    • 2014-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 2020-12-07
    相关资源
    最近更新 更多