Du verkar vilja ha en korskoppling av arrayvärdena (grupperade efter rownum
och name
). Detta är inte en standard JSON-struktur, så du bör inte förvänta dig att kunna göra detta med en enda applikation av json_table
.
Här är ett sätt att göra detta med två anrop till json_table
. I det första anropet använder du en kapslad sökväg för att få bara namnen, men du behåller fortfarande adressmatriserna. I ett andra samtal packar du upp adresserna, separat för varje rad som skapas av det första samtalet.
Notera användningen av en optimeringstips i den yttre select
. Detta behövs, för utan det kommer optimeraren att försöka en olaglig "unnesting" av sidofogen (outer apply
) och skicka sedan ett fel, istället för att lämna frågan som den är. (Detta är en mycket vanlig och irriterande vana hos optimeraren:den försöker något som är ogiltigt och sedan klagar den på det.)
Även rownum
är ett reserverat nyckelord - du kan inte använda det som ett kolumnnamn i utdata. (Tekniskt kan du, med extra arbete, men det är bäst att tro att du inte kan.)
with
t as (
select *
from json_Table(
'{
"Rownum": "1",
"Name": "John",
"AddressArray":["Address1", "Address2"],
"TextObj":[{"mName" : "Carol","lName" : "Cena"},
{"mName" : "Mark","lName" : "Karlo"}
]
}',
'$' columns (
rownr number path '$.Rownum',
name varchar2(100) path '$.Name',
addressArray varchar2(4000) format json path '$.AddressArray',
nested path '$.TextObj[*]'
columns (mName varchar2(100) path '$.mName',
lName varchar2(100) path '$.lName'
)
)
)
)
select /*+ no_query_transformation */ rownr, name, mname, lname, address
from t
outer apply
json_table (t.addressArray, '$[*]'
columns (address varchar2(10) path '$')
)
;
Utdata:
ROWNR NAME MNAME LNAME ADDRESS
----- ------ ------ ------ ----------
1 John Carol Cena Address1
1 John Carol Cena Address2
1 John Mark Karlo Address1
1 John Mark Karlo Address2