jsonb cross join 在 Postgres 中没有 return N*M 行
jsonb cross join did not return N*M rows in Postgres
CREATE TABLE mytable (
id int,
user_id text,
changes jsonb,
exercise_entry_id int
);
INSERT INTO mytable VALUES
(1, 'foo', '["a","b"]', 3),
(2, 'foo', '["c","d"]', 3);
交叉连接查询:
SELECT
mytable.*,
elems
FROM
mytable cross join
jsonb_array_elements(changes) as elems
order by mytable.id;
但是这个查询 returns 只有 4 行,如附图所示。交叉连接应该 return 8 行。现在只有 return 4 行,我错过了什么?
这是横向交叉连接。我在手册上找到它。
When a FROM item contains LATERAL cross-references, evaluation
proceeds as follows: for each row of the FROM item providing the
cross-referenced column(s), or set of rows of multiple FROM items
providing the columns, the LATERAL item is evaluated using that row or
row set's values of the columns. The resulting row(s) are joined as
usual with the rows they were computed from. This is repeated for each
row or set of rows from the column source table(s).
此查询 returns 8 行是 mytable
行 (2) 和所有数组的所有元素的笛卡尔积 changes
(4):
select
mytable.*,
elems
from mytable
cross join (
select jsonb_array_elements(changes) as elems
from mytable
) s
order by id;
与子查询的横向连接比较(returns 4行):
select
mytable.*,
elems
from mytable
cross join lateral (
select jsonb_array_elements(changes) as elems
) s
order by id;
子查询可以被一个简单的函数调用所取代,在这种情况下 lateral
这个词是可选的。
查找详细说明in the documentation.
如果您在 FROM
子句中使用 table 函数,则它隐含地是一个 LATERAL
连接,因此它会将每一行与该行的函数结果连接起来。
Table functions appearing in FROM
can also be preceded by the key word LATERAL, but for functions the key word is optional; the function's arguments can contain references to columns provided by preceding FROM items in any case.
也许这可以帮助实现您的需求
with temp as
(
select jsonb_array_elements( changes) from mytable
)
select * from mytable m1
cross join temp
结果:
CREATE TABLE mytable (
id int,
user_id text,
changes jsonb,
exercise_entry_id int
);
INSERT INTO mytable VALUES
(1, 'foo', '["a","b"]', 3),
(2, 'foo', '["c","d"]', 3);
交叉连接查询:
SELECT
mytable.*,
elems
FROM
mytable cross join
jsonb_array_elements(changes) as elems
order by mytable.id;
但是这个查询 returns 只有 4 行,如附图所示。交叉连接应该 return 8 行。现在只有 return 4 行,我错过了什么?
这是横向交叉连接。我在手册上找到它。
When a FROM item contains LATERAL cross-references, evaluation proceeds as follows: for each row of the FROM item providing the cross-referenced column(s), or set of rows of multiple FROM items providing the columns, the LATERAL item is evaluated using that row or row set's values of the columns. The resulting row(s) are joined as usual with the rows they were computed from. This is repeated for each row or set of rows from the column source table(s).
此查询 returns 8 行是 mytable
行 (2) 和所有数组的所有元素的笛卡尔积 changes
(4):
select
mytable.*,
elems
from mytable
cross join (
select jsonb_array_elements(changes) as elems
from mytable
) s
order by id;
与子查询的横向连接比较(returns 4行):
select
mytable.*,
elems
from mytable
cross join lateral (
select jsonb_array_elements(changes) as elems
) s
order by id;
子查询可以被一个简单的函数调用所取代,在这种情况下 lateral
这个词是可选的。
查找详细说明in the documentation.
如果您在 FROM
子句中使用 table 函数,则它隐含地是一个 LATERAL
连接,因此它会将每一行与该行的函数结果连接起来。
Table functions appearing in
FROM
can also be preceded by the key word LATERAL, but for functions the key word is optional; the function's arguments can contain references to columns provided by preceding FROM items in any case.
也许这可以帮助实现您的需求
with temp as
(
select jsonb_array_elements( changes) from mytable
)
select * from mytable m1
cross join temp
结果: