Как отдельные строки повернуть и преобразовать в столбцы, используя аггрегатные функции

Есть такой 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
/
→ Ссылка