Как отдельные строки повернуть и преобразовать в столбцы, используя аггрегатные функции
Есть такой JSON
sJson clob := '{
"NumDoc":"63",
"Groups": [
{
"GroupCode":"ALM",
"Vals": [
{
"StValCode":"USD",
},
{
"StValCode":"CHF"
}
],
"GroupCode":"TLD",
"Vals": [
{
"StValCode":"USD",
},
{
"StValCode":"RUB"
}
]
}
]
}';
Есть распарсенная таблица table_1:
|id | parent_id | name | value |
+---+-----------+---------+-------+
| 1 | 0 | NumDoc | 63 |
| 2 | 0 | Groups | null |
| 4 | 3 | Group | ALM |
| 5 | 3 | Vals | null |
| 7 | 6 | ValCode | USD |
|10 | 9 | ValCode | CHF |
|11 | 3 | Group | TLD |
|12 | 3 | Vals | null |
|14 | 13 | ValCode | USD |
|17 | 16 | ValCode | RUB |
Мне нужно получить такой результат:
| Numdoc | Group | Valcode |
+--------+------+----------+
| 63 | ALM | USD |
| 63 | ALM | CHF |
| 63 | TLD | USD |
| 63 | TLD | RUB |
Мой код:
with t as( select * from(
select (case when c.name='NumDoc' then c.Value end) NumDoc,
(case when c.name='Group' then c.Value end) as Group,
(case when c.name='ValCode' then c.Value end) as ValCode,
rownum as rn
from table_1 c))
select NumDoc,
min(Group),
min(ValCode)
from(select t.*, row_number() over (partition by NumDoc, rn order by rn) as seqnum
from t) T
group by NumDoc,seqnum,Group, ValCode
Но результат селекта:
| Numdoc | Group | Valcode |
+--------+-------+---------+
| null | null | null |
| null | null | CHF |
| null | null | RUB |
| null | null | USD |
| null | ALM | null |
| null | TLD | null |
| 63 | null | null |
Ответы (1 шт):
Автор решения: 0xdb
→ Ссылка
Попробуйте по другому распарсить JSON документ:
with parsed as (
select rownum seq, p.*
from tjson j, json_table (j.doc, '$' columns (
NumDoc varchar2 (8) path '$.NumDoc',
nested path '$.Groups[*]' columns (
nested path '$.GroupCode[*]' columns (
grpseq for ordinality,
GroupCode varchar2(8) path '$'),
nested path '$.Vals[*]' columns (
StValCode varchar2(8) path '$.StValCode')
)
)) p),
q as (
select
p.*, sum (nvl2 (grpseq, 1, 0)) over (order by seq) grp
from parsed p
) select q1.NumDoc, q1.GroupCode, q2.StValCode
from q q1
join q q2 on q2.grp = q1.grpseq and q2.StValCode is not null
/
Даст ожидаемый результат:
NUMDOC GROUPCOD STVALCOD
-------- -------- --------
63 ALM USD
63 ALM CHF
63 TLD USD
63 TLD RUB
Данные для примера:
create table tjson (doc, check (doc is json)) as
select cast ('{ JSON из вопроса }' as varchar2 (4000)) from dual
/