[英]Nested json data not captured by JSON_TABLE in oracle sql
我正在使用 Oracle 12c(12.2) 读取表中的 json 数据。
SELECT jt.name,
jt.employee_id,
jt.company
FROM JSON_TABLE ( BFILENAME ('DB_DIR', 'vv.json')
我在 json output 中嵌套了数据。 嵌套数据中的 key:value 以记录的值"past_work": "NA"
。 对于它下面的其他许多记录,具有实际值,例如
"past_work": [{ "company": "XXXXX", "title": "XXXX"}]
但是因为完成的第一条记录具有值以及开始和结束括号 [],oracle 没有捕获下面的记录嵌套值。 知道如何捕获以下记录吗?
示例:如下所示的实际数据
SELECT
jt.company,
jt.title
FROM
JSON_TABLE(
'{
"employee_data": [
{ "employee_id": "111",
"past_work": "N/A"
},
{ "employee_id": "222",
"past_work": [
{"company": "XXXXX", "title": "XXXX"},
{"company": "YYYYY", "title": "YYYY"}
]
},
{ "employee_id": "333",
"past_work": [
{"company": "XXXXX", "title": "XXXX"},
{"company": "YYYYY", "title": "YYYY"}
]
}
]
}',
'$.past_work[*]'
COLUMNS (
company VARCHAR2(100) PATH '$.company',
title VARCHAR2(100) PATH '$.title'
)
)
AS jt
现在,当我执行上述语句时,我得到 null 用于 emplyee_id 333 及以下的公司价值。
谢谢
如果past_work
应该是一个过去(company, title)
对的数组,那么编码“no history”的正确方法是不要使用像"N/A"
这样的字符串值,而是应该使用一个空数组,正如我在下面的代码中所示。 如果你按照自己的方式去做,你仍然可以提取数据,但它会异常混乱。 如果您使用JSON,请正确使用。
另外,你说你想提取公司和头衔。 就这些? 这是没有意义的。 相反,您可能希望提取每个员工的员工 ID 以及工作历史。 在工作历史中,我添加了一个“for ordinality”列(以显示哪个公司是第一个,哪个是第二个等)如果您不需要它,只需将其省略即可。
要访问嵌套列,您必须使用columns
规范中的nested
子句。
select employee_id, ord, company, title
from json_table(
'{
"employee_data": [
{ "employee_id": "111",
"past_work": [ ]
},
{ "employee_id": "222",
"past_work": [
{"company": "XXXXX", "title": "XXXX"},
{"company": "YYYYY", "title": "YYYY"}
]
},
{ "employee_id": "333",
"past_work": [
{"company": "XXXXX", "title": "XXXX"},
{"company": "YYYYY", "title": "YYYY"}
]
}
]
}', '$.employee_data[*]'
columns (
employee_id varchar2(10) path '$.employee_id',
nested path '$.past_work[*]'
columns (
ord for ordinality,
company varchar2(10) path '$.company',
title varchar2(10) path '$.title'
)
)
) jt
order by employee_id, ord;
Output:
EMPLOYEE_ID ORD COMPANY TITLE
----------- --- ------- -----
111
222 1 XXXXX XXXX
222 2 YYYYY YYYY
333 1 XXXXX XXXX
333 2 YYYYY YYYY
首先,json 代码段格式不正确,它必须被{}
包围才能被解析为 json object...
{"past_work": [{ "company": "XXXXX", "title": "XXXX"}]}
然后,您可以告诉 json 解析器您要从past_work
元素中提取行...
JSON_TABLE(<yourJsonString>, '$.past_work[*]')
[*]
告诉解析器past_work
是一个数组,并将该数组处理为 json 对象的行,而不是将整个数组作为单个 json object 返回。
这给出了类似...
SELECT
jt.company,
jt.title
FROM
JSON_TABLE(
'{
"past_work": [
{"company": "XXXXX", "title": "XXXX"},
{"company": "YYYYY", "title": "YYYY"}
]
}',
'$.past_work[*]'
COLUMNS (
company VARCHAR2(100) PATH '$.company',
title VARCHAR2(100) PATH '$.title'
)
)
AS jt
有关更多详细信息,我建议阅读文档:
编辑:更新的示例,几乎是文档中的复制和粘贴
SELECT
jt.*
FROM
JSON_TABLE(
'{
"XX_data":[
{
"employee_id": "E1",
"full_name": "E1 Admin",
"past_work": "N/A"
},
{
"employee_id": "E2",
"full_name": "E2 Admin",
"past_work": [
{"company": "E2 PW1 C", "title": "E2 PW1 T"},
{"company": "E2 PW2 C", "title": "E2 PW2 T"},
]
},
]
}',
'$.XX_data[*]'
COLUMNS (
employee_id VARCHAR2(100) PATH '$.employee_id',
full_name VARCHAR2(100) PATH '$.full_name',
past_work VARCHAR2(100) PATH '$.past_work',
NESTED PATH '$.past_work[*]'
COLUMNS (
past_work_company VARCHAR2(100) PATH '$.company',
past_work_title VARCHAR2(100) PATH '$.title'
)
)
)
AS jt
感谢大家的评论。 已要求产品团队提供正确格式的数据。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.