具有空值的 json_array_elements
Posted
技术标签:
【中文标题】具有空值的 json_array_elements【英文标题】:json_array_elements with null values 【发布时间】:2017-04-24 21:30:53 【问题描述】:我在 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 中的错误吗?
【问题讨论】:
【参考方案1】:您使用了正确的功能,但使用了错误的JOIN
。如果您(可能)在JOIN
的一侧没有行并且您想保留JOIN
另一侧的行并使用NULL
s 来“填充”行,您需要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) 时隐含)。
http://rextester.com/KNW13145
编辑:您的原始查询不直接涉及JOIN
,但更糟糕的是:您在SELECT
子句中使用了SRF。这几乎类似于CROSS JOIN
,但实际上是it has its own rules。 Don't use that 除非您确切地知道自己在做什么以及为什么需要它。
【讨论】:
谢谢 - 很好的回答,左连接比 klin 的案例语句更干净【参考方案2】:这不是错误。 json_array_elements_text('[null]')
返回 null
,json_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)
【讨论】:
我同意 json_array_elements_text 像你描述的那样工作,为什么这是正确的行为? 因为'[null]'::json
和'[]'::json
是有区别的。第一个数组包含 null,第二个为空。该函数无法从空数组返回任何内容。【参考方案3】:
解决我自己的问题,我有一个可能的答案,但似乎一团糟
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
【讨论】:
以上是关于具有空值的 json_array_elements的主要内容,如果未能解决你的问题,请参考以下文章