设置
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
在任何情况下都可以包含对前面项提供的列的引用。
列表中的函数的关键字始终
LATERAL
是可选的。这不是您查询中的问题。FROM
显式
JOIN
绑定比列表中的逗号更强FROM
。这就是问题所在。请参阅:您的第二个查询在逻辑上是错误的。在两者的结果与 连接之前
json_to_record(json_to_parse.block)
,绑定到,这与早期对 的引用相矛盾。因此出现错误。persons
json_to_parse
json_to_parse.block
FROM
列表本身中逗号并没有错。只是当您将两个表之间的主要连接条件放在where 的ON
orUSING
子句中时,通常更容易阅读和维护JOIN
。(并且它会产生功能差异!)。在正确OUTER JOIN
和适当的地方自由使用逗号。当我们给出意见时,我会这样写你的疑问:
或者,如果你想拼写出来:
TL;DR;不要将逗号连接与显式连接混用。事实上,根本不要使用逗号连接。
第二个查询中有一个逗号连接。逗号连接的解释如下,
CROSS JOIN
因此您似乎希望查询的解释如下:它确实有效,因为它
LATERAL
是可选的。但是因为逗号连接的优先级比显式连接语法低,所以实际发生的情况是这样的:
* 我知道 Postgres 不支持这种语法,但其他 DBMS 支持,而且你也可以使用子查询
由于您现在有一种子查询,
LATERAL
因此不是可选的。现在应该很明显为什么它不起作用:隐式括号将推INNER JOIN persons... ON...
入单独的范围。来自文档:
逗号连接已过时。显式连接是在 SQL-92 中引入的,在极少数情况下使用逗号连接更易读。始终支持显式连接语法。