Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 选择无关联的记录_Sql_Oracle - Fatal编程技术网

Sql 选择无关联的记录

Sql 选择无关联的记录,sql,oracle,Sql,Oracle,假设我有3张桌子: People ------------- PID | NAME ------------- 1 Bob 2 Garry 3 Alex 4 Peter 5 Victor Tasks ------------- TID | TASK ------------- 1 Work 2 Work Hard 3 Work Harder 以及将任务分配给人员的表 Assigns -

假设我有3张桌子:

People
-------------
PID   |  NAME
-------------
1       Bob
2       Garry
3       Alex
4       Peter
5       Victor

Tasks
-------------
TID   |  TASK
-------------
1       Work
2       Work Hard
3       Work Harder
以及将任务分配给人员的表

Assigns
-------------
PID   |  TID
-------------
1       2
2       1
4       3
问题:
如何选择未被分配任何任务的人员?

左侧加入方法将起作用,但以下两种方法可能更容易阅读:

1。不在

SELECT NAME
FROM People
WHERE PID NOT IN
(
    SELECT PID
    FROM Assigns
)
2。不存在

SELECT NAME
FROM People
WHERE NOT EXISTS
(
    SELECT *
    FROM Assigns
    WHERE People.PID = Assigns.PID
)
结果

Alex
Victor
相关的


左连接方法将起作用,但这里还有两种方法更容易阅读:

1。不在

SELECT NAME
FROM People
WHERE PID NOT IN
(
    SELECT PID
    FROM Assigns
)
2。不存在

SELECT NAME
FROM People
WHERE NOT EXISTS
(
    SELECT *
    FROM Assigns
    WHERE People.PID = Assigns.PID
)
结果

Alex
Victor
相关的


在子选择中使用NOT比使用LEFT-JOIN和NULL对性能的影响更大

SELECT NAME
   FROM People
      LEFT JOIN Assigns
         on People.PID = Assigns.PID
   where
      Assigns.PID IS NULL

通过使用LEFT-JOIN方法,People表将执行一次,并根据索引find连接到第二个表。实际上,它不会查询整个第二个“Assigns”文件,以查找所有可能的连接(不一定利用索引)。左连接直接利用索引,或者查找记录,或者不查找记录。如果没有,PID将为NULL,从而表明在分配表中找不到该人员。

使用NOT in子选择可能比LEFT-JOIN和预期NULL对性能的影响更大

SELECT NAME
   FROM People
      LEFT JOIN Assigns
         on People.PID = Assigns.PID
   where
      Assigns.PID IS NULL

通过使用LEFT-JOIN方法,People表将执行一次,并根据索引find连接到第二个表。实际上,它不会查询整个第二个“Assigns”文件,以查找所有可能的连接(不一定利用索引)。左连接直接利用索引,或者查找记录,或者不查找记录。如果它没有,PID将是空的,从而指示在分配表中找不到人。

你对左连接的感觉是零方法?是的,Sergej Popov,这应该很好,但是性能可能是个问题。@阿斯塔德,谢谢,我以后会考虑这一点,但是对于我的水平来说,更容易理解这一点。对于我目前的任务来说,性能不是一个主要问题。很高兴你得到了你想要的答案。X-@markbyers,这篇文章写得不错,但在摘要中确实有一个However语句。在大的表上会有什么表现?你对左边连接的感觉是什么?是的,“Sergej Popov,这应该很好,但是性能可能是个问题。”阿斯塔德,谢谢你,我会为将来考虑这个问题,但是对于我的水平来说,更容易理解这一点。对于我目前的任务来说,性能不是一个主要问题。很高兴你得到了你想要的答案。X-@markbyers,这篇文章写得不错,但在摘要中确实有一个However语句。如果Oracle为不在解决方案和左连接解决方案选择相同的执行计划,我不会感到惊讶。如果Oracle为不在解决方案和左连接解决方案选择相同的执行计划,我也不会感到惊讶