SQL:使用联接过滤数据是错误的?

SQL:使用联接过滤数据是错误的?,sql,database,postgresql,Sql,Database,Postgresql,例如,我有以下表格: animal ----------------------- animal_id | animal_name ----------------------- owners ----------------------- owner_id | owner_name ----------------------- owners_animals -------------------- owner_id | animal_id -------------------- 我想

例如,我有以下表格:

animal
-----------------------
animal_id | animal_name
-----------------------

owners
-----------------------
owner_id | owner_name
-----------------------

owners_animals
--------------------
owner_id | animal_id
--------------------
我想找到没有主人的动物,因此我执行以下查询:

select animal_name 
from (select * from animals) as a 
    left join (select * from owners_animals) as o on (a.animal_id = o.animal_id) 
where owner_id is NULL
这种使用联接过滤数据的方法是否可以接受且安全?对于相同的模式,是否有更好的替代方案来获得相同的结果?

使用Not:


另外,将owners\u anists.animal\u id的索引设置为尽可能快地进行此筛选

假设没有任何特定于postgres的内容,我不熟悉postgres,那么下面的内容更容易理解

Select * From animals a left outer join owners_animals oa On a.animal_id = oa.animal_id Where oa.owner_id is NULL 永远不要做,从SELECT*FROM表格,只从表格做,左连接也是如此。你写的东西太冗长了

SELECT animal_name
FROM animals
LEFT JOIN owners_animals
  USING ( animal_id )
WHERE owner_id IS NULL;
话虽如此,我通常喜欢notexists选项,因为它不让owner_id为NULL片段


在联接的表上使用foo与foo=foo相同,只是结果集中只有一个表。

忽略我的post-Nick表更好。这种形式更难遵循,但适当的索引可以更快地运行。运行速度不快,它们的计划都是一样的,顺便说一句,我发现很容易理解远程部分没有挂起的工件,不存在使意图非常清楚。@Evan-我认为PostgreSQL不一定是这样,我认为它确实进行了连接,需要进行测试,尽管……手头没有服务器。有人能测试吗?很确定计划是一样的,你必须注意的那个不在,不存在,不存在,不存在,左外连接。。。IS NULL将得到相同的计划。是否使用支持的跨平台?我以前从未见过它。我相信它在规范中,它永远都在Pg中。+1可能是比使用相关子查询性能更好的解决方案。我认为您有一个小的输入错误:o.animal\u id应该是oa.animal\u I出于好奇,您为什么使用派生表,例如,从tbl中选择*作为t,它们与表本身相同,例如,tbl作为t?
SELECT animal_name
FROM animals
LEFT JOIN owners_animals
  USING ( animal_id )
WHERE owner_id IS NULL;