当数组中的元素数改变时,为什么下面的查询行为会改变?
以下代码段在同一查询上扩展了两个数组,并具有两种不同的行为:
CROSS JOIN
所有这些操作均在 Postgres 9.5.2 中执行:
CREATE TABLE test(a text, b jsonb, c jsonb);
INSERT INTO test VALUES
('A', '["b1","b2"]', '["c1","c2"]'),
('B', '["b1","b2"]', '["c1","c2","c3"]');
SELECT a, jsonb_array_elements_text(b) b, jsonb_array_elements_text(c) c
FROM test;
这是结果:
A b1 c1
A b2 c2
B b1 c1
B b2 c2
B b1 c3
B b2 c1
B b1 c2
B b2 c3
这是我期望的:
A b1 c1
A b1 c2
A b2 c1
A b2 c2
B b1 c1
B b2 c2
B b1 c3
B b2 c1
B b1 c2
B b2 c3
答案 0 :(得分:1)
在SELECT
列表中组合多个返回集合的函数不在SQL标准中,在SQL标准中,所有返回集合的元素都进入FROM
列表。您可以在Postgres中执行此操作,但是在版本10最终经过消毒之前,它曾经表现出令人惊讶的行为。
所有这些都不与数据类型jsonb
或函数jsonb_array_elements_text()
直接相关-除了它是一个返回集合的函数之外。
如果要可靠地使用笛卡尔积,而不取决于您的Postgres版本,请改用CROSS JOIN LATERAL
(至少需要Postgres 9.3):
SELECT t.a, jb.b, jc.c
FROM test t
, jsonb_array_elements_text(t.b) jb(b)
, jsonb_array_elements_text(t.c) jc(c)
ORDER BY t.a, ???; -- your desired order seems arbitrary beyond a
FROM
列表(,
)中的逗号基本上是CROSS JOIN LATERAL
的简短语法。
请参阅:
您的实际问题的解释:
当数组中的元素数改变时,为什么下面的查询行为会改变?