AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 343949
Accepted
J. Mini
J. Mini
Asked: 2024-12-01 23:30:55 +0800 CST2024-12-01 23:30:55 +0800 CST 2024-12-01 23:30:55 +0800 CST

如果 LATERAL 对于表值函数是可选的,那么为什么没有它这个查询会出错?

  • 772

设置

CREATE TABLE persons
(
  person_id int not null,
  name TEXT 
);

INSERT INTO persons VALUES
(1, 'Adam'),
(2, 'Paul'),
(3, 'Tye'),
(4, 'Sarah');

CREATE TABLE json_to_parse
(
  person_id int not null,
  block json
);

INSERT INTO json_to_parse VALUES
  (1, '{"size": "small", "love": "x"}'),
  (2, '{"size": "medium", "love": "xx"}'),
  (3, '{"size": "big", "love": "xxx"}');

错误

运行没有问题

SELECT
  *
FROM
  json_to_parse
CROSS JOIN LATERAL
  json_to_record(json_to_parse.block) AS my_json(size TEXT, love TEXT)
INNER JOIN
  persons
ON
  persons.person_id = json_to_parse.person_id;

但这并不

SELECT
  *
FROM
  json_to_parse,
  json_to_record(json_to_parse.block) AS my_json(size TEXT, love TEXT)
INNER JOIN
  persons
ON
  persons.person_id = json_to_parse.person_id;

我收到错误“对表“json_to_parse”的 FROM 子句条目的引用无效”

为什么第二个查询会出错?文档说得很清楚,LATERAL对于表值函数来说,这是可选的

中出现的表函数FROM前面也可以加上关键字LATERAL,但对于函数来说,关键字是可选的;函数的参数FROM在任何情况下都可以包含对前面项提供的列的引用。

dbfiddle

postgresql
  • 2 2 个回答
  • 348 Views

2 个回答

  • Voted
  1. Best Answer
    Erwin Brandstetter
    2024-12-02T06:28:12+08:002024-12-02T06:28:12+08:00

    列表中的函数的关键字始终LATERAL 是可选的。这不是您查询中的问题。FROM

    显式JOIN绑定比列表中的逗号更强FROM。这就是问题所在。请参阅:

    • Postgres 中的 [FROM x, y] 是什么意思?

    您的第二个查询在逻辑上是错误的。在两者的结果与 连接之前json_to_record(json_to_parse.block),绑定到,这与早期对 的引用相矛盾。因此出现错误。persons json_to_parsejson_to_parse.block

    FROM列表本身中逗号并没有错。只是当您将两个表之间的主要连接条件放在where 的ONorUSING子句中时,通常更容易阅读和维护JOIN。(并且它会产生功能差异!)。在正确OUTER JOIN和适当的地方自由使用逗号。

    当我们给出意见时,我会这样写你的疑问:

    SELECT *  -- really all columns from all tables?
    FROM   persons p
    JOIN   json_to_parse jp USING (person_id)
         , json_to_record(jp.block) AS bl(size text, love text);
    

    或者,如果你想拼写出来:

    ...
    CROSS  JOIN LATERAL json_to_record(jp.block) AS bl(size text, love text);
    
    • 6
  2. Charlieface
    2024-12-02T02:04:16+08:002024-12-02T02:04:16+08:00

    TL;DR;不要将逗号连接与显式连接混用。事实上,根本不要使用逗号连接。

    第二个查询中有一个逗号连接。逗号连接的解释如下,CROSS JOIN因此您似乎希望查询的解释如下:

    FROM
      json_to_parse
    CROSS JOIN
      json_to_record(json_to_parse.block) AS my_json(size TEXT, love TEXT)
    INNER JOIN
      persons
    ON
      persons.person_id = json_to_parse.person_id
    

    它确实有效,因为它LATERAL是可选的。

    但是因为逗号连接的优先级比显式连接语法低,所以实际发生的情况是这样的:

    FROM
      json_to_parse
    CROSS JOIN (
        json_to_record(json_to_parse.block) AS my_json(size TEXT, love TEXT)
        INNER JOIN
          persons
        ON
          persons.person_id = json_to_parse.person_id
    )
    

    * 我知道 Postgres 不支持这种语法,但其他 DBMS 支持,而且你也可以使用子查询

    由于您现在有一种子查询,LATERAL因此不是可选的。现在应该很明显为什么它不起作用:隐式括号将推INNER JOIN persons... ON...入单独的范围。

    来自文档:

    子句JOIN将两个FROM项目组合在一起,为了方便起见,我们将其称为“表”,但实际上它们可以是任何类型的FROM项目。如有必要,请使用括号来确定嵌套顺序。如果没有括号,JOIN则从左到右嵌套。无论如何,JOIN其绑定程度都比分隔列表项目的逗号更紧密FROM。


    逗号连接已过时。显式连接是在 SQL-92 中引入的,在极少数情况下使用逗号连接更易读。始终支持显式连接语法。

    • 2

相关问题

  • 我可以在使用数据库后激活 PITR 吗?

  • 运行时间偏移延迟复制的最佳实践

  • 存储过程可以防止 SQL 注入吗?

  • PostgreSQL 中 UniProt 的生物序列

  • PostgreSQL 9.0 Replication 和 Slony-I 有什么区别?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve