Sql JSON_表筛选器条件问题
我正在尝试使用JSON_table将对象的JSON数组映射到关系表列。Sql JSON_表筛选器条件问题,sql,json,oracle,Sql,Json,Oracle,我正在尝试使用JSON_table将对象的JSON数组映射到关系表列。 部件数组由指令数组数组组成。每个指令数组包含具有三个名称-值对的一致名称的对象。“名称”字段的值始终为“系列”、“特征”或“价格”。它们在数组中的顺序并不总是一致的。我想我可以在columns子句中使用一个过滤条件来将正确的值映射到正确的列 WITH STR AS ( select ' { "Parts": [ { "instruction": [ { "name
部件数组由指令数组数组组成。每个指令数组包含具有三个名称-值对的一致名称的对象。“名称”字段的值始终为“系列”、“特征”或“价格”。它们在数组中的顺序并不总是一致的。我想我可以在columns子句中使用一个过滤条件来将正确的值映射到正确的列
WITH STR AS (
select
'
{
"Parts": [
{
"instruction": [
{
"name": "Family",
"value": "AJE",
"type": "0"
},
{
"name": "Feature",
"value": "AJKA",
"type": "0"
},
{
"name": "Price",
"value": "0",
"type": "0"
}
]
},
{
"instruction": [
{
"name": "Feature",
"value": "AJKB",
"type": "0"
},
{
"name": "Family",
"value": "AJA",
"type": "0"
}
]
}
]
}
' JSTR
FROM DUAL)
SELECT JT.*
FROM STR SO,
JSON_TABLE(SO.JSTR, '$.Parts[*].instruction[*]'
COLUMNS ("Family" PATH '$."value"?(@.name == "Family" )',
"Feature" PATH '$."value"?(@.name == "Feature")',
"Price" PATH '$."value"?(@.name == "Price")'
)
)
AS "JT"
显示代码时,它返回五行,所有字段都为空。
我意识到上面的代码是错误的。下面是另一种尝试。此代码将返回数据(已注释掉的筛选条件和硬编码的数组索引),但列数据映射错误
JSON_TABLE(SO.JSTR, '$.Parts[*]' --ERROR ON ERROR
COLUMNS ("Family" PATH '$.instruction[0]."value"', --?(@.name == "Family" )
"Feature" PATH '$.instruction[1]."value"', --?(@.name == "Feature")
"Price" PATH '$.instruction[2]."value"' --?(@.name == "Price")
)
Family Feature Price
------ ------- -----
AJE AJKA 0
AJKA AJE
I'm trying to return this:
Family Feature Price
------ ------- -----
AJE AJKA 0
AJA AJKB
更新:ORD应计算指令,而不是单个值 要将所需的值放在正确的列中,请调整路径:
SELECT JT.*
FROM STR SO,
JSON_TABLE(
SO.JSTR, '$.Parts[*].instruction'
COLUMNS (
ord for ordinality,
nested path '$[*]' columns (
Family path '$?(@.name == "Family").value',
Feature path '$?(@.name == "Feature").value',
Price path '$?(@.name == "Price").value'
)
)
)
AS "JT";
ORD FAMILY FEATURE PRICE
1 AJE
1 AJKA
1 0
2 AJKB
2 AJA
现在只需按ORD分组:
SELECT ord,
max(family) family,
max(feature) feature,
max(price) price
FROM STR SO,
JSON_TABLE(
SO.JSTR, '$.Parts[*].instruction'
COLUMNS (
ord for ordinality,
nested path '$[*]' columns (
Family path '$?(@.name == "Family").value',
Feature path '$?(@.name == "Feature").value',
Price path '$?(@.name == "Price").value'
)
)
)
AS "JT"
group by ord
order by ord;
ORD FAMILY FEATURE PRICE
1 AJE AJKA 0
2 AJA AJKB
最重要的是,Stew Ashton一个选项是确定子查询中嵌套路径“$”部分“[*]”指令“[*]”的
有序性
值,该子查询将用于排序按名称
列值分组的行数(),通过系列
和功能
列进行旋转
:
SELECT "Family", "Feature" FROM
(
SELECT value, name , ROW_NUMBER() OVER (PARTITION BY name ORDER BY rn) AS rn
FROM STR,
JSON_TABLE(jstr, '$'
COLUMNS (NESTED PATH '$."Parts"[*]."instruction"[*]'
COLUMNS (rn FOR ORDINALITY,
value VARCHAR2 PATH '$."value"',
name VARCHAR2 PATH '$."name"')
)) )
PIVOT
(
MAX(value) FOR name IN ('Family' AS "Family", 'Feature' AS "Feature")
)
ORDER BY rn
我希望StackOverflow的人总是在前面指出他们的Oracle数据库版本 不管怎么说,这个黑客似乎在18c版本中有效:
SELECT ord,
max(json_value(jt.Family, '$.value')) family,
max(json_value(jt.Feature, '$.value')) feature,
max(json_value(jt.Price, '$.value')) price
FROM STR SO,
JSON_TABLE(
SO.JSTR, '$.Parts[*].instruction'
COLUMNS (
ord for ordinality,
nested path '$[*]' columns (
Family format json path '$?(@.name == "Family")',
Feature format json path '$?(@.name == "Feature")',
Price format json path '$?(@.name == "Price")'
)
)
)
AS "JT"
group by ord
order by ord;
更好的解决方案是简化JSON并使用PIVOT子句来操作结果:
select family, feature, price
from (
SELECT jt.ord, jt.name, jt.value
from str,
JSON_TABLE(
str.JSTR, '$.Parts[*].instruction'
COLUMNS (
ord for ordinality,
nested path '$[*]' columns (
name varchar2(100) path '$.name',
value varchar2(100) path '$.value'
)
)
)
AS "JT"
)
pivot(max(value) for name in ('Family' as Family, 'Feature' as Feature, 'Price' as Price))
order by ord;
非常感谢。这很有帮助。我确实在18c上遇到了语法错误,但我在livesql上试过了,它现在说是在19c上,并且工作正常。我仍然需要尝试将其修改为18c。