ORACLE JSON_TABLE 我需要从数组中获取 2 列
Posted
技术标签:
【中文标题】ORACLE JSON_TABLE 我需要从数组中获取 2 列【英文标题】:ORACLE JSON_TABLE I need to get 2 columns from an array 【发布时间】:2020-12-13 21:36:48 【问题描述】:我有这个 SQL 代码
SELECT * FROM JSON_TABLE (('
[
"tipodenunciaid": [1,2],
"municipioid": [1,2]
]
'), '$[*]' COLUMNS (tipodenunciaid integer PATH '$.tipodenunciaid[*]', municipioid integer PATH '$.municipioid[*]'));
我想得到下一个结果:
我的查询有什么问题?
非常感谢。
【问题讨论】:
输入和输出是如何关联的?municipioid
的值 4
和 5
发生了什么?
输出只是我需要结构的一个例子。
您需要向我们展示您想要的特定数据的实际输出。否则就不清楚你到底在追求什么。
我只需要这 2 个数组变成 2 列..
你不能单独使用 JSON 函数来做到这一点——原因很简单,JSON 结构对单独属性的数组值没有意义。最大的问题是您的输入数据,而不是您的查询。如果这些值应该与您在输出中显示的那样相关,那么 JSON 应该是一个对象数组,每个对象都具有您在 your JSON 中的顶层所具有的两个属性。按照您现在获取数据的方式,您需要将数组值提取到两个单独子查询中的列中,然后按序数连接。
【参考方案1】:
你不能这样使用json_table()
。如果您希望两个数组不嵌套在不同的列中,并根据每个数组中每个元素的位置排列,那么一种选择是将每个数组分别扩展为行,使用ordinality
跟踪每个元素的位置,然后加入两个结果集。 full join
可以方便地容纳每个数组中不相等数量的元素:
with
data as (
select ' "tipodenunciaid": [1,2,3,4], "municipioid": [1,2,3,4,5] ' as js from dual
),
t as (
select t.*
from data d
cross apply json_table(
d.js,
'$.tipodenunciaid[*]' columns (rn for ordinality, tipodenunciaid integer path '$')
) t
),
m as (
select m.*
from data d
cross apply json_table(
d.js,
'$.municipioid[*]' columns (rn for ordinality, municipioid integer path '$')
) m
)
select t.tipodenunciaid, m.municipioid
from t
full join m on m.rn = t.rn
Demo on DB Fiddle.
【讨论】:
【参考方案2】:您可以使用两个OUTER APPLY
s 和FOR ORDINALITY
来生成数组的纵坐标以将表连接到自身:
SELECT j.id,
CASE
WHEN t.id = m.id OR t.id > m.max_id OR m.id IS NULL
THEN tipodenunciaid
END AS tipodenunciaid,
CASE
WHEN t.id = m.id OR m.id > t.max_id OR t.id IS NULL
THEN municipioid
END AS municipioid
FROM table_name j
OUTER APPLY (
SELECT id,
tipodenunciaid,
MAX(id) OVER () AS max_id
FROM JSON_TABLE(
j.json,
'$.tipodenunciaid[*]'
COLUMNS (
id FOR ORDINALITY,
tipodenunciaid integer PATH '$'
)
)
) t
OUTER APPLY (
SELECT id,
municipioid,
MAX(id) OVER () AS max_id
FROM JSON_TABLE(
j.json,
'$.municipioid[*]'
COLUMNS (
id FOR ORDINALITY,
municipioid integer PATH '$'
)
)
) m
WHERE t.id = m.id
OR t.id IS NULL
OR ( m.id > t.max_id AND t.id = t.max_id )
OR m.id IS NULL
OR ( t.id > m.max_id AND m.id = m.max_id );
其中,对于样本数据:
CREATE TABLE table_name ( id, json ) AS
SELECT 1, '"tipodenunciaid":[1,2],"municipioid":[1,2]' FROM DUAL UNION ALL
SELECT 2, '"tipodenunciaid":[],"municipioid":[3,4]' FROM DUAL UNION ALL
SELECT 3, '"tipodenunciaid":[5],"municipioid":[]' FROM DUAL UNION ALL
SELECT 4, '"tipodenunciaid":[6,7],"municipioid":[6]' FROM DUAL UNION ALL
SELECT 5, '"tipodenunciaid":[8],"municipioid":[8,9]' FROM DUAL;
输出:
身份证 | TIPODENUNCIAID | MUNICIPIOID -: | -------------: | ----------: 1 | 1 | 1 1 | 2 | 2 2 | 空 | 3 2 | 空 | 4 3 | 5 | 空 4 | 6 | 6 4 | 7 | 空 5 | 8 | 8 5 | 空 | 9
db小提琴here
【讨论】:
以上是关于ORACLE JSON_TABLE 我需要从数组中获取 2 列的主要内容,如果未能解决你的问题,请参考以下文章
oracle sql中的JSON_TABLE未捕获嵌套的json数据
JPA 标准 API 和 Oracle JSON_TABLE 函数