Het lijkt erop dat u een kruiskoppeling wilt van de arraywaarden (gegroepeerd op rownum
en name
). Dit is geen standaard JSON-structuur, dus je moet niet verwachten dat je dit kunt doen met een enkele toepassing van json_table
.
Hier is een manier om dit te doen met twee aanroepen naar json_table
. In de eerste aanroep gebruikt u een genest pad om alleen de namen te krijgen, maar u behoudt nog steeds de adresreeksen. Bij een tweede oproep pakt u de adressen uit, afzonderlijk voor elke rij die door de eerste oproep is geproduceerd.
Let op het gebruik van een optimalisatiehint in de buitenste select
. Dit is nodig, want zonder dit zal de optimizer een illegale "unnesting" van de laterale join proberen (outer apply
) en geef vervolgens een fout, in plaats van de query te laten zoals deze is. (Dit is een veel voorkomende en vervelende gewoonte van de optimizer:hij probeert iets dat ongeldig is en klaagt er dan over.)
Ook rownum
is een gereserveerd trefwoord - u kunt het niet als kolomnaam in de uitvoer gebruiken. (Technisch gezien kun je dat, met extra werk, maar het is het beste om te geloven dat je dat niet kunt.)
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 '$')
)
;
Uitgang:
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