Sembra che tu voglia un cross join dei valori dell'array (raggruppati per rownum
e name
). Questa non è una struttura JSON standard, quindi non dovresti aspettarti di poterlo fare con una singola applicazione di json_table
.
Ecco un modo per farlo con due chiamate a json_table
. Nella prima chiamata, usi un percorso nidificato per ottenere solo i nomi, ma mantieni comunque le matrici di indirizzi. In una seconda chiamata, spacchetta gli indirizzi, separatamente per ogni riga prodotta dalla prima chiamata.
Nota l'uso di un suggerimento per l'ottimizzazione nel select
esterno . Questo è necessario, perché senza di esso l'ottimizzatore tenterà un "unnesting" illegale del join laterale (outer apply
) e quindi genera un errore, invece di lasciare la query così com'è. (Questa è un'abitudine molto comune e fastidiosa dell'ottimizzatore:prova qualcosa che non è valido e poi si lamenta.)
Inoltre, rownum
è una parola chiave riservata:non puoi usarla come nome di colonna nell'output. (Tecnicamente puoi, con lavoro aggiuntivo, ma è meglio credere che non puoi.)
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 '$')
)
;
Uscita:
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