子选择是否进行隐式连接?

时间:2014-07-27 21:50:38

标签: sql postgresql

我有一个似乎有效的sql 查询,但我真的不明白为什么。因此,如果有人能帮助解释最新情况,我将非常感激:

QUERY RETURNS:所有没有任何评论的组织都不是由创建组织记录的顾问创建的。

SELECT \"organisations\".* 
FROM \"organisations\"  
WHERE \"organisations\".\"id\" NOT IN 
  (SELECT \"comments\".\"commentable_id\" 
     FROM \"comments\"  
     WHERE \"comments\".\"commentable_type\" = 'Organisation' 
     AND (comments.author_id != organisations.consultant_id) 
     ORDER BY \"comments\".\"created_at\" ASC
  )

似乎正确地这样做了。

我不理解的部分是为什么(comments.author_id != organisations.consultant_id)正在工作!?我不明白postgres甚至知道“subselect”中的“组织”是什么?它没有在这里定义。

如果这是作为我加入组织评论的联接而写的,那么我完全理解你如何做这样的事情,但在这种情况下它是一个子选择。它如何知道如何映射评论和组织表并排除(comments.author_id != organisations.consultant_id)

的表格

2 个答案:

答案 0 :(得分:0)

该子选择连续发生,因此它可以看到该行的所有列。使用此

可能会获得更好的性能
select organisations.* 
from organisations
where not exists (
    select 1
    from comments
    where
        commentable_type = 'organisation'  and
        author_id != organisations.consultant_id
)

请注意,没有必要限定commentable_type,因为comments中的那个优先于子选择之外的任何其他人。如果comments没有consultant_id列,那么就可以将其限定符用尽,但不建议更好的可读性。

您的查询中的order by只会为您购买,只需添加费用。

答案 1 :(得分:0)

您正在运行相关子查询。 http://technet.microsoft.com/en-us/library/ms187638(v=sql.105).aspx

这通常用于所有数据库。 WHERE子句中的子查询可以引用父查询中使用的表,而且它们经常这样做。

话虽如此,您当前的查询可能会写得更好。

以下是一种方法,使用带注释的外部联接,根据您的条件找不到匹配项 -

select o.*
  from organizations o
  left join comments c
    on c.commentable_type <> 'Organisation'
   and c.author_id = o.consultant_id
 where c.commentable_id is null