为什么在组合外部和内部连接时表的顺序很重要?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
Run Code Online (Sandbox Code Playgroud)
结果:
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.
Run Code Online (Sandbox Code Playgroud)
当这些组在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
Run Code Online (Sandbox Code Playgroud)
Dav*_*sta 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
Run Code Online (Sandbox Code Playgroud)
我认为它由解析器解释如下:
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
)
Run Code Online (Sandbox Code Playgroud)
如果是这样,那么在最里面的连接"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
Run Code Online (Sandbox Code Playgroud)
Cow*_*wan 18
我认为没有人能够很好地解决这个问题,或者解释得非常好.你正在结合'旧式'(theta)和'新式'(ANSI)连接,我强烈怀疑这些连接是以你不期望的方式进行分组的.这样看:
SELECT * FROM a, b JOIN c ON a.x = c.x
Run Code Online (Sandbox Code Playgroud)
就像说
SELECT * FROM a, (b JOIN c on a.x = c.x)
Run Code Online (Sandbox Code Playgroud)
括号中的东西代表一堆表合并到一个虚拟表中,与"a"连接的theta-join.显然'a'表不能成为连接的一部分,因为它只是稍后加入.扭转它,你正在做
SELECT * FROM b, (a JOIN c on a.x = c.x)
Run Code Online (Sandbox Code Playgroud)
这是完全可以理解的,很好.我不确定为什么你没有使用ANSI连接语法,但这似乎有点奇怪(对于必须维护它的人来说是残忍的!)
| 归档时间: |
|
| 查看次数: |
30315 次 |
| 最近记录: |