Oracle
 sql >> Database >  >> RDS >> Oracle

Analizza Json utilizzando Oracle SQL - JSON_TABLE

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