json_array_elements 具有空值
json_array_elements with null values
我在 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 中的错误吗?
这不是错误。 json_array_elements_text('[null]')
returns null
, json_array_elements_text('[]')
没有 return 任何东西。
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)
解决我自己的问题,我有一个可能的答案,但看起来一团糟
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
您使用了正确的功能,但使用了错误的 JOIN
。如果您(可能)在 JOIN
的一侧没有行并且您想保留 JOIN
另一侧的行并使用 NULL
s 到 "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
作为加入条件,但其实很笼统,当您使用 LATERAL
joins 时(当您直接在 FROM
子句中使用集合返回函数 (SRF) 时,这是隐含的)。
Edit:您的原始查询不直接涉及 JOIN
,但更糟糕的是:您在 SELECT
子句中使用了 SRF。这 几乎 类似于 CROSS JOIN
,但实际上 it has its own rules. 除非您确切地知道自己在做什么以及为什么需要这样做。
我在 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 中的错误吗?
这不是错误。 json_array_elements_text('[null]')
returns null
, json_array_elements_text('[]')
没有 return 任何东西。
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)
解决我自己的问题,我有一个可能的答案,但看起来一团糟
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
您使用了正确的功能,但使用了错误的 JOIN
。如果您(可能)在 JOIN
的一侧没有行并且您想保留 JOIN
另一侧的行并使用 NULL
s 到 "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
作为加入条件,但其实很笼统,当您使用 LATERAL
joins 时(当您直接在 FROM
子句中使用集合返回函数 (SRF) 时,这是隐含的)。
Edit:您的原始查询不直接涉及 JOIN
,但更糟糕的是:您在 SELECT
子句中使用了 SRF。这 几乎 类似于 CROSS JOIN
,但实际上 it has its own rules.