Оконные функции (лидерство / отставание) с коллекциями в Oracle SQL (PL / SQL) - PullRequest
0 голосов
/ 01 сентября 2018

Я хочу перенести сценарий SQL, который существует в PostgreSQL, на Oracle SQL. Вот пример данных:

NR                      GRD DT
00000000000000000001    06  01.01.13
00000000000000000001    06  01.01.13
00000000000000000001    21  01.01.13
00000000000000000002    06  01.01.13
00000000000000000002    21  01.01.13
00000000000000000004    01  31.03.13

Вот мой упрощенный код:

CREATE TYPE tbl_array AS TABLE OF NVARCHAR2(4000);

with prep as (
Select
    nr
    , cast(collect(grd) as tbl_array) grds
from
    test_table
group by
    nr                    
)
select 
    prep.*
    , lead(grds) over (order by nr) as lead_grds
from 
    prep

Но оконная функция не работает. Я получаю следующее сообщение об ошибке:

ORA-00932: несовместимые типы данных: ожидается - получено ORACLEANALYTICS.TBL_ARRAY

Это из-за созданного типа? Как я могу решить эту проблему? На втором шаге я хочу проверить пересечение коллекций с другими (уже работающими), поэтому они мне нужны. Это как-то возможно?

Приветствие Chris

1 Ответ

0 голосов
/ 01 сентября 2018

Вы можете использовать ROW_NUMBER() для симуляции LAG/LEAD:

with prep as (
  select
    nr, CAST(collect(grd) AS tbl_array) grds,ROW_NUMBER() OVER(ORDER BY nr) AS rn
  from tab
  group by nr                    
)
select p.nr, p.grds, p2.grds AS lead_grds
    --, lead(grds) over (order by nr) as lead_grds
from prep p
LEFT JOIN prep p2
  ON p2.rn = p.rn +1;

Выход из подготовительного:

┌──────────────────────┬────────────────────────────────┬────┐
│          NR          │              GRDS              │ RN │
├──────────────────────┼────────────────────────────────┼────┤
│ 00000000000000000001 │ HR.TBL_ARRAY('06', '21', '06') │  1 │
│ 00000000000000000002 │ HR.TBL_ARRAY('06', '21')       │  2 │
│ 00000000000000000004 │ HR.TBL_ARRAY('01')             │  3 │
└──────────────────────┴────────────────────────────────┴────┘

Вывод всего запроса:

┌──────────────────────┬──────────────────────────────┬──────────────────────────┐
│          NR          │             GRDS             │        LEAD_GRDS         │
├──────────────────────┼──────────────────────────────┼──────────────────────────┤
│ 00000000000000000001 │HR.TBL_ARRAY('06', '21', '06')│ HR.TBL_ARRAY('06', '21') │
│ 00000000000000000002 │HR.TBL_ARRAY('06', '21')      │ HR.TBL_ARRAY('01')       │
│ 00000000000000000004 │HR.TBL_ARRAY('01')            │                          │
└──────────────────────┴──────────────────────────────┴──────────────────────────┘

Эквивалент в PostgreSQL:

WITH prep AS (
  SELECT NR, ARRAY_AGG(GRD) AS grds
  FROM tab
  GROUP BY NR
)
SELECT prep.*, LEAD(grds) OVER(ORDER BY nr) AS lead_grds
FROM prep;

Демоверсия DBFiddle

...