【问题标题】:postgresql multi join syntaxpostgresql 多连接语法
【发布时间】:2012-04-29 17:16:21
【问题描述】:
SELECT sessions_compare.*
    FROM archive_sessions as f_session, sessions_compare
    LEFT JOIN archive_sessions as s_session ON (s_session.id = sessions_compare.second_session_id)
    LEFT JOIN consols as f_consol ON (f_session.console_id = f_consol.id)

    where sessions_compare.first_session_id = f_session.id

在执行 get 错误后

错误:对表“f_session”的 FROM 子句条目的引用无效 第 13 行:
LEFT JOIN consols 为 f_consol ON (f_session.console_id =...

提示:表“f_session”有一个条目,但无法从中引用 查询的一部分。

当我切换位置并拥有from 就像sessions_compare, archive_sessions as f_session 我得到类似的错误

错误:对表的 FROM 子句条目的引用无效 “会话_比较” 第 4 行:...archive_sessions 作为 s_session ON (s_session.id = session_c...

提示:表“sessions_compare”有一个条目,但不能 从查询的这一部分引用。

唯一有效的是

SELECT sessions_compare.*
    FROM sessions_compare
    LEFT JOIN archive_sessions as s_session ON (s_session.id = sessions_compare.second_session_id)

    ,archive_sessions as f_session

    LEFT JOIN consols as f_consol ON (f_session.console_id = f_consol.id)
    where sessions_compare.first_session_id = f_session.id

我的问题是正常吗?当使用来自表的多个连接需要在() 中时,我在 mysql 中的 Postgresql 中很年轻。

【问题讨论】:

  • 对表条目使用较短的相关名称标签可能会简化阅读。
  • 顺便说一句:当您编辑问题时,建议不要删除人们可能会做出反应的部分。我花了一些时间修复这个愚蠢的查询,而你所做的只是将它从问题中删除。
  • 不是关于查询,而是关于语法。我让这个查询工作,如果以这种方式创建查询是正常的,我会更伤心

标签: postgresql left-join


【解决方案1】:

将主查询更改为 JOIN(并添加/缩短一些相关名称)似乎可以解决问题。

DROP SCHEMA fuzz CASCADE;
CREATE SCHEMA fuzz;
SET search_path='fuzz';

create table archive_sessions ( id INTEGER NOT NULL
 , console_id INTEGER NOT NULL, game_id INTEGER NOT NULL);
create table sessions_compare (first_session_id INTEGER NOT NULL
 , second_session_id INTEGER NOT NULL);
create table consols (id INTEGER NOT NULL);
create table games (id INTEGER NOT NULL);
create table localizations ( consols_id INTEGER NOT NULL, bars_id INTEGER NOT NULL);
create table bars ( id_bars INTEGER NOT NULL, area_id INTEGER NOT NULL);
create table areas ( id_areas INTEGER NOT NULL );

SELECT sco.*
    FROM archive_sessions as ase
    JOIN sessions_compare sco ON sco.first_session_id = ase.id

    LEFT JOIN archive_sessions as ss ON (ss.id = sco.second_session_id)
    LEFT JOIN consols as sc ON (ss.console_id = sc.id)
    LEFT JOIN games as sg ON (ss.game_id = sg.id)
    LEFT JOIN localizations as sl ON (sc.id = sl.consols_id)
    LEFT JOIN bars as sb ON (sl.bars_id = sb.id_bars)
    LEFT JOIN areas as sa ON (sb.area_id = sa.id_areas)



    LEFT JOIN consols as fc ON (ase.console_id = fc.id)
    LEFT JOIN games as fg ON (ase.game_id = fg.id)
    LEFT JOIN localizations as fl ON (fc.id = fl.consols_id)
    LEFT JOIN bars as fb ON (fl.bars_id = fb.id_bars)
    LEFT JOIN areas as fa ON (fb.area_id = fa.id_areas)

    -- WHERE sco.first_session_id = ase.id
        ;

【讨论】:

  • 但我不想更改此查询,我希望它保持原样
  • 我唯一做的事情(除了一些重命名)是用等效的FROM x JOIN y 构造替换FROM x, y,并将WHERE 子句置于ON 条件中。 (这正是@Catcall 所建议的,顺便说一句)
【解决方案2】:

是的,这是 PostgreSQL 中记录的行为。

In any case JOIN binds more tightly than the commas separating FROM items.

这意味着 PostgreSQL 的行为就像它通过在评估 FROM 子句中的逗号列表之前评估 JOIN 子句来构建其工作表。

通常认为最佳实践是始终使用 JOIN 子句;永远不要在 FROM 子句中放置多个表名。

【讨论】:

    猜你喜欢
    • 2016-03-14
    • 2011-06-02
    • 1970-01-01
    • 2015-11-29
    • 1970-01-01
    • 2015-01-16
    • 1970-01-01
    • 2020-08-09
    • 1970-01-01
    相关资源
    最近更新 更多