Вам не нужно использовать иерархический запрос, и вы можете выполнять его независимо от настроек NLS, используя TRUNC( date_value, 'IW' )
, чтобы найти начало недели ISO, которая всегда является понедельником.
Итак:
TRUNC( SYSDATE, 'IW' ) - TRUNC( TRUNC( SYSDATE, 'MM' ), 'IW' )
Найдет количество дней между началом недели ISO, содержащей первый день месяца, и началом текущей недели ISO.Умножив это на 5/7
, мы получим количество дней недели.
Затем вам нужно будет узнать, сколько из этих дней произошло в предыдущем месяце, и вычесть их.Это можно найти, используя:
LEAST( TRUNC( SYSDATE, 'MM' ) - TRUNC( TRUNC( SYSDATE, 'MM' ), 'IW' ), 5 )
и сколько дней нужно добавить для текущей недели;который задается следующим образом:
LEAST( TRUNC( SYSDATE ) - TRUNC( SYSDATE, 'IW' ) + 1, 5 )
Таким образом, общее количество можно найти с помощью:
SELECT ( TRUNC( SYSDATE, 'IW' ) - TRUNC( TRUNC( SYSDATE, 'MM' ), 'IW' ) ) * 5 / 7
+ LEAST( TRUNC( SYSDATE ) - TRUNC( SYSDATE, 'IW' ) + 1, 5 )
- LEAST( TRUNC( SYSDATE, 'MM' ) - TRUNC( TRUNC( SYSDATE, 'MM' ), 'IW' ), 5 )
AS Num_Week_Days
FROM DUAL;
Пример с несколькими днями:
WITH calendar ( date_value ) AS (
SELECT DATE '2018-12-01' + LEVEL - 1
FROM DUAL
CONNECT BY LEVEL <= 15
)
SELECT date_value,
TO_CHAR( date_value, 'DY' ) AS day,
( TRUNC( date_value, 'IW' ) - TRUNC( TRUNC( date_value, 'MM' ), 'IW' ) ) * 5 / 7
+ LEAST( TRUNC( date_value ) - TRUNC( date_value, 'IW' ) + 1, 5 )
- LEAST( TRUNC( date_value, 'MM' ) - TRUNC( TRUNC( date_value, 'MM' ), 'IW' ), 5 )
AS Num_Week_Days
FROM Calendar;
Выходные данные:
DATE_VALUE DAY NUM_WEEK_DAYS
---------- --- -------------
2018-12-01 SAT 0
2018-12-02 SUN 0
2018-12-03 MON 1
2018-12-04 TUE 2
2018-12-05 WED 3
2018-12-06 THU 4
2018-12-07 FRI 5
2018-12-08 SAT 5
2018-12-09 SUN 5
2018-12-10 MON 6
2018-12-11 TUE 7
2018-12-12 WED 8
2018-12-13 THU 9
2018-12-14 FRI 10
2018-12-15 SAT 10