带有空值的json_array_elements

时间:2017-04-24 21:30:54

标签: json postgresql postgresql-9.4

我在Windows上使用PostgreSQL 9.4.5,64位。 我有一些不规则大小的数组。我想用 json_array_elements扩展数组,类似于以下代码

with outside as (select (json_array_elements('[[],[11],[21,22,23]]'::json)) aa, json_array_elements('[1,2,3]'::json)bb) 
select json_array_elements_text(aa), bb from outside

然而,当我运行这个时,我得到了

aa | bb
------- 
11 |  2
21 |  3
22 |  3
23 |  3

列aa中的空数组与bb栏中的值1一起被删除

我想得到

aa   | bb
---------- 
null |  1
11   |  2
21   |  3
22   |  3
23   |  3

另外,这是PostgreSQL中的一个错误吗?

3 个答案:

答案 0 :(得分:3)

您正在使用正确的功能,但错误JOIN。如果您(可能)在JOIN&的一侧没有排。你想保留JOIN&的另一边的行。使用NULL来" pad"行,您需要OUTER JOIN

with outside as (
    select json_array_elements('[[],[11],[21,22,23]]') aa,
           json_array_elements('[1,2,3]') bb
) 
select    a, bb
from      outside
left join json_array_elements_text(aa) a on true

注意:将on true视为加入条件时,可能看起来很奇怪,但当您使用{{3}时,它实际上非常普遍(在FROM子句中直接使用集合返回函数(SRF)时隐式)。

LATERAL joins

编辑:您的原始查询不直接涉及JOIN,但更糟糕的是:您在SELECT子句中使用了SRF。这个几乎就像一个CROSS JOIN,但实际上是http://rextester.com/KNW13145it has its own rules除非您确切知道自己在做什么以及为什么需要这样做。

答案 1 :(得分:1)

这不是错误。 json_array_elements_text('[null]')返回nulljson_array_elements_text('[]')不返回任何内容。

with outside as (
    select (
        json_array_elements('[[],[11],[21,22,23]]'::json)) aa, 
        json_array_elements('[1,2,3]'::json) bb
) 
select elem as aa, bb
from outside,
json_array_elements_text(case when aa::text = '[]' then '[null]'::json else aa end) elem;

 aa | bb 
----+----
    | 1
 11 | 2
 21 | 3
 22 | 3
 23 | 3
(5 rows)    

答案 2 :(得分:0)

解决我自己的问题,我有一个可能的答案,但它看起来像一团糟

With initial as (select '[[],[11],[21,22,23]]'::json as a, '[1,2,3]'::json as b),
    Q1 as (select json_array_elements(a) as aa, json_array_elements(b) bb from initial),
    Q2 as (select ARRAY[aa->>0, aa->>1, aa->>2] as aaa, bb as bbb, ARRAY[0,1,2] as ccc from q1), 
    -- where the indicices are computed in a separate query by looping from 0 to json_array_length(...)
    Q3 as (select unnest(aaa) as aaaa, bbb as bbbb, unnest(ccc) as cccc from q2)

Select aaaa, bbbb from q3 where aaaa is not null or cccc = 0