SELECT 列表中两次 jsonb_array_elements_text() 的结果不一致

Inconsistent results with jsonb_array_elements_text() twice in the SELECT list

为什么当数组中的元素数量发生变化时,下面查询的行为会发生变化?

以下代码段在同一查询中扩展了两个数组并具有两种不同的行为:

所有这些都在 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

SELECT 列表中组合多个 set-returning 函数不在 SQL 标准中,其中所有 set-returning 元素都进入 FROM 列表。您可以在 Postgres 中做到这一点,但它在版本 10 之前表现出令人惊讶的行为,最终被清理干净。

所有这些都与数据类型 jsonb 或函数 jsonb_array_elements_text() 没有直接关系 - 除了它是一个 set-returning 函数。

如果您想要笛卡尔积,可靠且不依赖于您的 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 的简短语法。

参见:

您实际问题的解释:

Why does the behavior of the query below change when the number of elements in the array changes?