Функция задержки для поиска значения предыдущей записи с отсутствующей предыдущей записью

У меня есть требование получить предыдущую строку или записи задержки, где отсутствуют некоторые предыдущие идентификаторы.

База данных: Oracle 12c

Пример данных:

ВЕТКАПЕРИОДКОЛ-ВО
10531917
10532020
10532132
10532261
10731917
10732118
10732216
10831921
10832227

Я хочу результаты в следующем формате: Если вы видите для ветви 107: период 319 отсутствует, а для ветви 108: 320 321 отсутствует. Поэтому, если есть какие-либо отсутствующие предыдущие записи, столбцы prev_period_<>_Qty должны быть равны 0.

Не могли бы вы помочь в достижении этого.

ВЕТКАПЕРИОДКОЛ-ВОPREV_PERIOD_1_КОЛ-ВОPREV_PERIOD_2_QTYPREV_PERIOD_3_QTY
10531917000
105320201700
1053213220170
10532261322017
10731917000
107321180170
1073221618017
10831921000
108322270021

образец данных очень поможет. Вы можете подготовить скрипку db<>?

Oguen 16.03.2022 15:57

Ссылка на скрипку @Oguen db: db-fiddle.com/f/jzXY7oz2e9svBbCRE7srtj/0

Vicki 16.03.2022 16:08

Мне также нужен запрос для версии Oracle 11g, может ли кто-нибудь помочь в этом?

Vicki 16.03.2022 16:39
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
3
21
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В Oracle 12 вы можете использовать MATCH_RECOGNIZE для построчной обработки:

SELECT branch,
       period,
       qty,
       COALESCE(prev_period_1_qty, 0) AS prev_period_1_qty,
       COALESCE(prev_period_2_qty, 0) AS prev_period_2_qty,
       COALESCE(prev_period_3_qty, 0) AS prev_period_3_qty
FROM   table_name
MATCH_RECOGNIZE (
  PARTITION BY branch
  ORDER     BY period DESC
  MEASURES
    curr.period AS period,
    curr.qty    AS qty,
    prev1.qty   AS prev_period_1_qty,
    prev2.qty   AS prev_period_2_qty,
    prev3.qty   AS prev_period_3_qty
  ONE ROW PER MATCH
  AFTER MATCH SKIP TO NEXT ROW
  PATTERN (curr prev1? prev2? prev3?)
  DEFINE
    prev1 AS curr.period - 1 = period,
    prev2 AS curr.period - 2 = period,
    prev3 AS curr.period - 3 = period
)
ORDER BY branch, period

Или, используя LAG:

SELECT branch,
       period,
       qty,
       CASE
       WHEN p1 = period - 1
       THEN q1 ELSE 0
       END AS prev_period_1_qty,
       CASE
       WHEN p1 = period - 2 THEN q1
       WHEN p2 = period - 2 THEN q2
       ELSE 0
       END AS prev_period_2_qty,
       CASE
       WHEN p1 = period - 3 THEN q1
       WHEN p2 = period - 3 THEN q2
       WHEN p3 = period - 3 THEN q3
       ELSE 0
       END AS prev_period_3_qty
FROM   (
  SELECT t.*,
         LAG(period, 1) OVER (PARTITION BY branch ORDER BY period) AS p1,
         LAG(period, 2) OVER (PARTITION BY branch ORDER BY period) AS p2,
         LAG(period, 3) OVER (PARTITION BY branch ORDER BY period) AS p3,
         LAG(qty, 1, 0) OVER (PARTITION BY branch ORDER BY period) AS q1,
         LAG(qty, 2, 0) OVER (PARTITION BY branch ORDER BY period) AS q2,
         LAG(qty, 3, 0) OVER (PARTITION BY branch ORDER BY period) AS q3
  FROM   table_name t
)

Что для примера данных:

CREATE TABLE table_name (BRANCH, PERIOD, QTY) AS
SELECT 105, 319, 17 FROM DUAL UNION ALL
SELECT 105, 320, 20 FROM DUAL UNION ALL
SELECT 105, 321, 32 FROM DUAL UNION ALL
SELECT 105, 322, 61 FROM DUAL UNION ALL
SELECT 107, 319, 17 FROM DUAL UNION ALL
SELECT 107, 321, 18 FROM DUAL UNION ALL
SELECT 107, 322, 16 FROM DUAL UNION ALL
SELECT 108, 319, 21 FROM DUAL UNION ALL
SELECT 108, 322, 27 FROM DUAL;

Оба выхода:

BRANCHPERIODQTYPREV_PERIOD_1_QTYPREV_PERIOD_2_QTYPREV_PERIOD_3_QTY
10531917000
105320201700
1053213220170
10532261322017
10731917000
107321180170
1073221618017
10831921000
108322270021

дб <> рабочий пример здесь

Спасибо! вы также можете помочь, как это сделать в oracle 11g?

Vicki 16.03.2022 16:32

@Вики Обновлено.

MT0 16.03.2022 16:51

Спасибо за вашу помощь! Решение функции задержки сработало. Спасибо еще раз!

Vicki 16.03.2022 17:04

Другие вопросы по теме