Zdá se, že chcete křížové spojení hodnot pole (seskupených podle rownum
a name
). Toto není standardní struktura JSON, takže byste neměli očekávat, že to budete moci udělat s jedinou aplikací json_table
.
Zde je jeden způsob, jak toho dosáhnout pomocí dvou volání json_table
. V prvním volání použijete vnořenou cestu k získání pouze jmen, ale stále zachováte pole adres. Při druhém hovoru rozbalíte adresy zvlášť pro každý řádek vytvořený prvním hovorem.
Všimněte si použití nápovědy optimalizátoru ve vnějším select
. To je potřeba, protože bez něj se optimalizátor pokusí o nelegální "rozložení" bočního spojení (outer apply
) a poté vyvolá chybu, namísto ponechání dotazu tak, jak je. (Toto je velmi běžný a nepříjemný zvyk optimalizátoru:zkouší něco, co je neplatné, a pak si na to stěžuje.)
Také rownum
je vyhrazené klíčové slovo – nemůžete ho použít jako název sloupce ve výstupu. (Technicky můžete, s dodatečnou prací, ale nejlepší je věřit, že nemůžete.)
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 '$')
)
;
Výstup:
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