Вы можете использовать LAG
с предложением IGNORE NULLS
и оператором CASE
:
Тестовые данные :
CREATE TABLE oracle_calendar (
DATE_D DATE,
DAY_OF_WEEK_DESC_EN VARCHAR2(9) GENERATED ALWAYS AS ( CAST( RTRIM( TO_CHAR( DATE_D, 'Day' ) ) AS VARCHAR2(9) ) ),
IS_WORKING_DAY NUMBER(1,0)
);
INSERT INTO oracle_calendar( date_d, is_working_day )
SELECT DATE '2010-01-01', 0 FROM DUAL UNION ALL
SELECT DATE '2010-01-02', 0 FROM DUAL UNION ALL
SELECT DATE '2010-01-03', 0 FROM DUAL UNION ALL
SELECT DATE '2010-01-04', 1 FROM DUAL UNION ALL
SELECT DATE '2010-01-05', 1 FROM DUAL UNION ALL
SELECT DATE '2010-01-06', 1 FROM DUAL UNION ALL
SELECT DATE '2010-01-07', 1 FROM DUAL UNION ALL
SELECT DATE '2010-01-08', 1 FROM DUAL UNION ALL
SELECT DATE '2010-01-09', 0 FROM DUAL UNION ALL
SELECT DATE '2010-01-10', 0 FROM DUAL;
Запрос:
SELECT date_d,
LAG( CASE is_working_day WHEN 1 THEN date_d END, 1, NULL )
IGNORE NULLS OVER ( ORDER BY date_d) AS last_working_day,
day_of_week_desc_en,
is_working_day
FROM oracle_calendar
Выход :
DATE_D | LAST_WORKING_DAY | DAY_OF_WEEK_DESC_EN | IS_WORKING_DAY
:-------- | :--------------- | :------------------ | -------------:
01-JAN-10 | <em>null</em> | Friday | 0
02-JAN-10 | <em>null</em> | Saturday | 0
03-JAN-10 | <em>null</em> | Sunday | 0
04-JAN-10 | <em>null</em> | Monday | 1
05-JAN-10 | 04-JAN-10 | Tuesday | 1
06-JAN-10 | 05-JAN-10 | Wednesday | 1
07-JAN-10 | 06-JAN-10 | Thursday | 1
08-JAN-10 | 07-JAN-10 | Friday | 1
09-JAN-10 | 08-JAN-10 | Saturday | 0
10-JAN-10 | 08-JAN-10 | Sunday | 0
db <> скрипка здесь
Запрос 2 :
Чтобы избавиться от всех значений NULL
при запуске и использовать первый рабочий день:
SELECT date_d,
COALESCE(
LAG( CASE is_working_day WHEN 1 THEN date_d END, 1, NULL )
IGNORE NULLS OVER ( ORDER BY date_d),
CASE is_working_day
WHEN 1
THEN date_d
ELSE LEAD( CASE is_working_day WHEN 1 THEN date_d END, 1, NULL )
IGNORE NULLS OVER ( ORDER BY date_d)
END
) AS last_working_day,
day_of_week_desc_en,
is_working_day
FROM oracle_calendar
DATE_D | LAST_WORKING_DAY | DAY_OF_WEEK_DESC_EN | IS_WORKING_DAY
:-------- | :--------------- | :------------------ | -------------:
01-JAN-10 | 04-JAN-10 | Friday | 0
02-JAN-10 | 04-JAN-10 | Saturday | 0
03-JAN-10 | 04-JAN-10 | Sunday | 0
04-JAN-10 | 04-JAN-10 | Monday | 1
05-JAN-10 | 04-JAN-10 | Tuesday | 1
06-JAN-10 | 05-JAN-10 | Wednesday | 1
07-JAN-10 | 06-JAN-10 | Thursday | 1
08-JAN-10 | 07-JAN-10 | Friday | 1
09-JAN-10 | 08-JAN-10 | Saturday | 0
10-JAN-10 | 08-JAN-10 | Sunday | 0
дБ <> скрипка здесь