首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Inner和outer join;from表的顺序重要吗?

Inner和outer join;from表的顺序重要吗?
EN

Stack Overflow用户
提问于 2008-10-09 13:00:55
回答 4查看 31.7K关注 0票数 17

为什么在组合外部连接和内部连接时,表的顺序很重要?postgres会出现以下故障:

代码语言:javascript
复制
SELECT grp.number AS number,     
       tags.value AS tag   
FROM groups grp,
     insrel archiverel  
LEFT OUTER JOIN ownrel ownrel ON grp.number = ownrel.dnumber   
LEFT OUTER JOIN tags tags ON tags.number = ownrel.snumber   
WHERE archiverel.snumber = 11128188 AND    
      archiverel.dnumber = grp.number 

with结果:

代码语言:javascript
复制
ERROR:  invalid reference to FROM-clause entry for table "grp" LINE 5: LEFT OUTER JOIN ownrel ownrel ON grp.number = ownrel.d... 
^ HINT:  There is an entry for table "grp", but it cannot be referenced from this part of the query.

当组在FROM it all中颠倒时:

代码语言:javascript
复制
SELECT  grp.number AS number,     
        tags.value AS tag   
FROM    insrel archiverel,
        groups grp
LEFT OUTER JOIN ownrel ownrel ON grp.number = ownrel.dnumber   
LEFT OUTER JOIN tags tags ON tags.number = ownrel.snumber   
WHERE   archiverel.snumber = 11128188 AND    
        archiverel.dnumber = grp.number 
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2008-10-09 13:39:29

我相信您可以认为这是一个运算符优先级问题。

当你写下这篇文章时:

代码语言:javascript
复制
FROM groups grp,
     insrel archiverel  
LEFT OUTER JOIN ownrel ownrel ON grp.number = ownrel.dnumber   
LEFT OUTER JOIN tags tags ON tags.number = ownrel.snumber   

我认为解析器会这样解释它:

代码语言:javascript
复制
FROM groups grp,
(
  (
     insrel archiverel  
     LEFT OUTER JOIN ownrel ownrel ON grp.number = ownrel.dnumber   
  )
LEFT OUTER JOIN tags tags ON tags.number = ownrel.snumber
)

如果是这样,那么在最里面的连接中,"grp“是未绑定的。

当您使用"groups“和"insrel”颠倒行时,最里面的连接应用于"groups“和"ownrel",因此它是有效的。

也许这样也行得通:

代码语言:javascript
复制
    FROM groups grp
         JOIN insrel archiverel  ON archiverel.dnumber = grp.number
    LEFT OUTER JOIN ownrel ownrel ON grp.number = ownrel.dnumber   
    LEFT OUTER JOIN tags tags ON tags.number = ownrel.snumber 
WHERE archiverel.snumber = 11128188
票数 20
EN

Stack Overflow用户

发布于 2008-10-09 13:39:04

我认为没有人能很好地理解这一点,或者解释得很好。你组合了'old style‘(theta)和'new style’(ANSI)连接,我强烈怀疑它们是以你意想不到的方式组合在一起的。这样看:

代码语言:javascript
复制
SELECT * FROM a, b JOIN c ON a.x = c.x

就像是在说

代码语言:javascript
复制
SELECT * FROM a, (b JOIN c on a.x = c.x)

其中括号中的东西表示一堆合并到一个虚拟表中的表,这些表将通过针对'a‘的theta-join进行连接。显然,'a‘表不能是连接的一部分,因为它只在以后被连接。反转过来,你就是在做

代码语言:javascript
复制
SELECT * FROM b, (a JOIN c on a.x = c.x)

这是完全可以理解的,也很好。我不知道为什么您不使用ANSI join语法来处理所有这些问题,这似乎有点奇怪(对于必须维护它的人来说也很残酷!)

票数 19
EN

Stack Overflow用户

发布于 2008-10-09 13:06:33

因为在第一个grp中,grp不是ON子句所属的联接的一部分。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/187146

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档