当前位置:  开发笔记 > 大数据 > 正文

内连接和外连接; 表格的顺序是重要的吗?

如何解决《内连接和外连接;表格的顺序是重要的吗?》经验,为你挑选了3个好方法。

为什么在组合外部和内部连接时表的顺序很重要?postgres失败如下:

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 

结果:

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中被反转时,一切正常:

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 

Dave Costa.. 20

我相信您可以将此视为运营商优先级问题.

当你写这个:

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   

我认为它由解析器解释如下:

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",因此它可以工作.

也许这也会起作用:

    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


Cowan.. 18

我认为没有人能够很好地解决这个问题,或者解释得非常好.你正在结合'旧式'(theta)和'新式'(ANSI)连接,我强烈怀疑这些连接是以你不期望的方式进行分组的.这样看:

SELECT * FROM a, b JOIN c ON a.x = c.x

就像说

SELECT * FROM a, (b JOIN c on a.x = c.x)

括号中的东西代表一堆表合并到一个虚拟表中,与"a"连接的theta-join.显然'a'表不能成为连接的一部分,因为它只是稍后加入.扭转它,你正在做

SELECT * FROM b, (a JOIN c on a.x = c.x)

这是完全可以理解的,很好.我不确定为什么你没有使用ANSI连接语法,但这似乎有点奇怪(对于必须维护它的人来说是残忍的!)



1> Dave Costa..:

我相信您可以将此视为运营商优先级问题.

当你写这个:

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   

我认为它由解析器解释如下:

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",因此它可以工作.

也许这也会起作用:

    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



2> Cowan..:

我认为没有人能够很好地解决这个问题,或者解释得非常好.你正在结合'旧式'(theta)和'新式'(ANSI)连接,我强烈怀疑这些连接是以你不期望的方式进行分组的.这样看:

SELECT * FROM a, b JOIN c ON a.x = c.x

就像说

SELECT * FROM a, (b JOIN c on a.x = c.x)

括号中的东西代表一堆表合并到一个虚拟表中,与"a"连接的theta-join.显然'a'表不能成为连接的一部分,因为它只是稍后加入.扭转它,你正在做

SELECT * FROM b, (a JOIN c on a.x = c.x)

这是完全可以理解的,很好.我不确定为什么你没有使用ANSI连接语法,但这似乎有点奇怪(对于必须维护它的人来说是残忍的!)



3> RB...:

因为在第一个grp不是ON子句所属的连接的一部分.

推荐阅读
跟我搞对象吧
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有