Wygląda na to, że chcesz połączyć krzyżowe wartości tablicy (pogrupowane według rownum
i name
). To nie jest standardowa struktura JSON, więc nie powinieneś oczekiwać, że będziesz w stanie to zrobić za pomocą pojedynczej aplikacji json_table
.
Oto jeden ze sposobów, aby to zrobić za pomocą dwóch wywołań json_table
. W pierwszym wywołaniu używasz zagnieżdżonej ścieżki, aby uzyskać tylko nazwy, ale nadal zachowujesz tablice adresów. W drugim połączeniu rozpakowujesz adresy, osobno dla każdego wiersza utworzonego przez pierwsze połączenie.
Zwróć uwagę na użycie podpowiedzi optymalizatora w zewnętrznym select
. Jest to potrzebne, ponieważ bez tego optymalizator spróbuje nielegalnego "rozgniecenia" łączenia bocznego (outer apply
), a następnie wyrzuć błąd, zamiast pozostawić zapytanie bez zmian. (Jest to bardzo powszechny i denerwujący nawyk optymalizatora:próbuje czegoś, co jest niepoprawne, a następnie narzeka na to.)
Również rownum
jest zastrzeżonym słowem kluczowym — nie można go użyć jako nazwy kolumny w wynikach. (Technicznie możesz, przy dodatkowej pracy, ale najlepiej wierzyć, że nie możesz.)
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 '$')
)
;
Wyjście:
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