sql >> Base de Datos >  >> RDS >> Oracle

Analizar Json usando Oracle SQL - JSON_TABLE

Parece que desea una unión cruzada de los valores de la matriz (agrupados por rownum y name ). Esta no es una estructura JSON estándar, por lo que no debe esperar poder hacer esto con una sola aplicación de json_table .

Aquí hay una forma de hacer esto con dos llamadas a json_table . En la primera llamada, usa una ruta anidada para obtener solo los nombres, pero aún conserva las matrices de direcciones. En una segunda llamada, desempaqueta las direcciones, por separado para cada fila producida por la primera llamada.

Tenga en cuenta el uso de una sugerencia de optimización en el exterior select . Esto es necesario, porque sin él, el optimizador intentará "desanidar" ilegalmente la unión lateral (outer apply ) y luego lanzar un error, en lugar de dejar la consulta como está. (Este es un hábito muy común y molesto del optimizador:prueba algo que no es válido y luego se queja).

Además, rownum es una palabra clave reservada; no puede usarla como nombre de columna en la salida. (Técnicamente puedes, con trabajo adicional, pero es mejor creer que no puedes).

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 '$')
     )
;

Salida:

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