Возвращает значение даты с n-й недели месяца в SQL Developer без создания функции - PullRequest
0 голосов
/ 30 сентября 2019

Я пишу запрос на выборку, который должен вернуть дату. Например: если мне нужна четвертая неделя пятницы текущего месяца, то я ожидаю 2019-09-27.

Но моя проблема в том, что я не хочу использовать какую-либо функцию.

Я пробовал ниже код

select next_day( (trunc(to_date('nov','mon'),'mm')-1), 'fri' ) + 21 from dual

Выше кода дает дату прошлой недели, но я ожидаю дату любой недели.

Ответы [ 2 ]

1 голос
/ 30 сентября 2019

Это зависит от того, как вы определяете, какая неделя в месяце.

Если хотите, чтобы первой неделей была изо-неделя, в которой любой день недели находится в месяце:

  • TRUNC( SYSDATE, 'MM' ) вы получите первый день месяца.
  • TRUNC( first_day_of_month, 'IW' ) урежет дату до начала изо-недели (то есть понедельника).
  • NEXT_DAY( monday_of_week_including_first_day_of_month, 'FRIDAY' ) найдет пятницу на изо-неделе, содержащей первый день месяца.
  • Если вы хотите пятницу четвертой изо-недели, то добавьте 3 недели:

Т.е. :

SELECT NEXT_DAY( TRUNC( TRUNC( SYSDATE, 'MM' ), 'IW' ) - INTERVAL '1' DAY, 'FRIDAY' ) + 3 * INTERVAL '7' DAY AS friday4,
       NEXT_DAY( TRUNC( TRUNC( SYSDATE, 'MM' ), 'IW' ) - INTERVAL '1' DAY, 'MONDAY' ) + 0 * INTERVAL '7' DAY AS monday1,
       NEXT_DAY( TRUNC( TRUNC( SYSDATE, 'MM' ), 'IW' ) - INTERVAL '1' DAY, 'SUNDAY' ) + 0 * INTERVAL '7' DAY AS sunday1
FROM   DUAL;
FRIDAY4   | MONDAY1   | SUNDAY1  
:-------- | :-------- | :--------
20-SEP-19 | 26-AUG-19 | 01-SEP-19

Если вы хотите использовать iso-недели, но начинайте с того, что первая неделя месяца - это iso-неделя, которая содержит первый четверг месяца (как используется для вычисления, когда неделя находится в пределах iso-года), вам нужно использовать дополнительную логику, чтобы определить это:

SELECT NEXT_DAY(
         TRUNC( TRUNC( SYSDATE, 'MM' ), 'IW' )
         + CASE
           WHEN TRUNC( TRUNC( SYSDATE, 'MM' ), 'IW' ) + INTERVAL '3' DAY >= TRUNC( SYSDATE, 'MM' )
           THEN INTERVAL '-1' DAY
           ELSE INTERVAL '6' DAY
           END,
         'FRIDAY'
       ) + 3 * INTERVAL '7' DAY
       AS friday4,
       NEXT_DAY(
         TRUNC( TRUNC( SYSDATE, 'MM' ), 'IW' )
         + CASE
           WHEN TRUNC( TRUNC( SYSDATE, 'MM' ), 'IW' ) + INTERVAL '3' DAY >= TRUNC( SYSDATE, 'MM' )
           THEN INTERVAL '-1' DAY
           ELSE INTERVAL '6' DAY
           END,
         'MONDAY'
       ) + 0 * INTERVAL '7' DAY
       AS monday4,
       NEXT_DAY(
         TRUNC( TRUNC( SYSDATE, 'MM' ), 'IW' )
         + CASE
           WHEN TRUNC( TRUNC( SYSDATE, 'MM' ), 'IW' ) + INTERVAL '3' DAY >= TRUNC( SYSDATE, 'MM' )
           THEN INTERVAL '-1' DAY
           ELSE INTERVAL '6' DAY
           END,
         'SUNDAY'
       ) + 0 * INTERVAL '7' DAY
       AS sunday4
FROM   DUAL;
FRIDAY4   | MONDAY1   | SUNDAY1  
:-------- | :-------- | :--------
27-SEP-19 | 02-SEP-19 | 08-SEP-19

Если вы хотите запуститьсчитая с первого дня месяца (независимо от того, какой это день недели):

SELECT NEXT_DAY( TRUNC( SYSDATE, 'MM' ) - INTERVAL '1' DAY, 'FRIDAY' ) + 3 * INTERVAL '7' DAY AS friday4,
       NEXT_DAY( TRUNC( SYSDATE, 'MM' ) - INTERVAL '1' DAY, 'MONDAY' ) + 0 * INTERVAL '7' DAY AS monday1,
       NEXT_DAY( TRUNC( SYSDATE, 'MM' ) - INTERVAL '1' DAY, 'SUNDAY' ) + 0 * INTERVAL '7' DAY AS sunday1
FROM   DUAL;
FRIDAY4   | MONDAY1   | SUNDAY1 
:-------- | :-------- | :--------
27-SEP-19 | 02-SEP-19 | 01-SEP-19

дБ <> fхолостой ход здесь

0 голосов
/ 30 сентября 2019

Вот один из вариантов;calendar CTE, который я создал, относится к сентябрю.

SQL> set ver off
SQL>
SQL> with calendar as
  2    (select trunc(sysdate, 'mm') + level - 1 datum
  3     from dual
  4     connect by level <= 30
  5    ),
  6  inter as
  7    (select datum,
  8       to_char(datum, 'w') week_in_month,
  9       to_char(datum, 'dy', 'nls_date_language=english') day
 10     from calendar
 11    )
 12  select datum
 13  from inter
 14  where day = '&day'
 15    and week_in_month = &week;
Enter value for day: tue
Enter value for week: 2

DATUM
----------
10.09.2019

SQL> /
Enter value for day: fri
Enter value for week: 3

DATUM
----------
20.09.2019

SQL>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...