Запрос Oracle для получения конца недели из заданного набора данных - PullRequest
0 голосов
/ 13 ноября 2018

У меня есть таблица в Oracle, где EOW столбцы указывают на конец недели. Я хочу написать запрос, чтобы получить дату ближайшего конца недели.

Таблица Cal

DAY         DAY OFTHE WEEK      EOW

20181026    FRI                 Y  
20181027    SAT                 N  
20181028    SUN                 N  
20181029    MON                 N  
20181030    TUE                 N   -->
20181031    WED                 N  
20181101    THU                 N  
20181102    FRI                 Y  -->  
20181103    SAT                 N  

Итак, когда я

select DAY , "logic" from cal where day = 20181030;

Что должно быть "логикой", чтобы я получал дату ближайшего конца недели, в этом случае 20181026.

Пожалуйста, помогите !!

Ответы [ 3 ]

0 голосов
/ 13 ноября 2018

Вам действительно нужна фиксированная таблица для этого? CTE может легко создать любой календарь, который вы хотите, поэтому - я воспользовался этой свободой, чтобы создать нечто подобное.

Я написал это шаг за шагом, чтобы вы могли следить за его выполнением. Начните с первого CTE (dates), затем перейдите к day_diff и т. Д.). Кажется, вы выбираете первый FRI, предшествующий текущей дате. Потому что для 20181030 ближайший конец недели - не 20181026 (4 дня до этой пятницы), а 20181102 (3 дня до этой пятницы).

В конце получается

SQL> with dates as
  2    (select
  3      -- add "level" (sequence of numbers from 1 to 60) to 1st of previous month
  4      trunc(add_months(sysdate, - 1), 'mm') + level - 1 datum,
  5      -- convert that date into a day name (MON, FRI, ...)
  6      to_char(trunc(add_months(sysdate, -1), 'mm') + level - 1, 'DY',
  7              'NLS_DATE_LANGUAGE=ENGLISH') dan,
  8      -- if day name is FRI, set EOW = Y. Else, it is N
  9      case when to_char(trunc(add_months(sysdate, -1), 'mm') + level - 1, 'DY',
 10                        'NLS_DATE_LANGUAGE=ENGLISH') = 'FRI' then 'Y'
 11           else 'N'
 12      end eow
 13     from dual
 14     connect by level <= 60  -- my CTE will have 60 dates; yours can have any number
 15    ),
 16  day_diff as
 17    (select datum, dan, eow,
 18       datum - to_date('&par_datum', 'dd.mm.yyyy') diff
 19    from dates
 20    ),
 21  diff_only_eow as
 22    (select datum, dan, eow, diff,
 23       row_number() over (order by diff desc) rn
 24     from day_diff
 25     where eow = 'Y'
 26       and diff <= 0
 27    )
 28  select datum, dan, eow, diff, rn
 29  from diff_only_eow
 30  where rn = 1;
Enter value for par_datum: 30.10.2018

DATUM    DAN          E       DIFF         RN
-------- ------------ - ---------- ----------
20181026 FRI          Y         -4          1

SQL>
0 голосов
/ 13 ноября 2018

Это может решить ваш запрос

select day, to_char(to_date(day,'YYYYMMDD'),'DY') f1,
    case to_char(to_date(day,'YYYYMMDD'),'DY')
        when 'FRI' then 0
        when 'SAT' then -1
        when 'SUN' then -2
        when 'MON' then -3
        when 'TUE' then 3
        when 'WED' then 2
        when 'THU' then 1
    end as f2,
    to_char(to_date(day,'YYYYMMDD')+ case to_char(to_date(day,'YYYYMMDD'),'DY')
        when 'FRI' then 0
        when 'SAT' then -1
        when 'SUN' then -2
        when 'MON' then -3
        when 'TUE' then 3
        when 'WED' then 2
        when 'THU' then 1
    end,'YYYYMMDD') as f3
from test_cal;


DAY      F1                F2 F3
-------- --------- ---------- --------
20181026 FRI                0 20181026
20181027 SAT               -1 20181026
20181028 SUN               -2 20181026
20181029 MON               -3 20181026
20181030 TUE                3 20181102
20181031 WED                2 20181102
20181101 THU                1 20181102
20181102 FRI                0 20181102
20181103 SAT               -1 20181102

9 rows selected.
0 голосов
/ 13 ноября 2018

Я думаю,

 If the date is 30-OCT-2018 (20181030), then you want last friday date as 26-OCT - 2018 (20181026). 

Другой сценарий:

If the date is 27-OCT-2018 (20181027), in that case also you want last friday date which is 26-OCT - 2018 (20181026).

Если мое предположение верно, тогда может работать следующий запрос:

   WITH TEMP1 AS
            (
             SELECT TO_CHAR(
                            TO_DATE('20181030','YYYYMMDD') ,'DD-MON-YY') AS DATE_TEST 
               FROM DUAL
             ) 
   SELECT next_day (TO_DATE(DATE_TEST,'DD-MON-YY')-7,'FRIDAY') Last_Friday
     FROM   TEMP1;

Будет отображаться вывод:

   LAST_FRIDAY
   26-OCT-18

Который вы можете конвертировать позже в нужном вам формате.

Контрольный пример 2

   WITH TEMP1 AS
        (
         SELECT TO_CHAR(
                        TO_DATE('20181103','YYYYMMDD') ,'DD-MON-YY') AS DATE_TEST 
           FROM DUAL
         ) 
   SELECT next_day (TO_DATE(DATE_TEST,'DD-MON-YY')-7,'FRIDAY') Last_Friday
 FROM   TEMP1;

Выход:

 LAST_FRIDAY
 02-NOV-18

Теперь нарушение вышеуказанного запроса:

В CTE используется предложение WITH.

  WITH TEMP1 AS
    (
     SELECT TO_CHAR(
                    TO_DATE('20181103','YYYYMMDD') ,'DD-MON-YY') AS DATE_TEST 
       FROM DUAL
     )

Здесь TO_DATE ('20181103', 'YYYYMMDD'), 'DD-MON-YY' - преобразует 20181103 в 03-NOV-2018.

Таким образом, результат предложения WITH (который является 03-NOV-2018) будет использоваться в другом запросе:

SELECT next_day (TO_DATE(DATE_TEST,'DD-MON-YY')-7,'FRIDAY') Last_Friday
  FROM   TEMP1;

Здесь DATE_TEST выводится из предложения with. Первый

 TO_DATE(DATE_TEST,'DD-MON-YY')-7

Это занимает предыдущие 7 дней с указанной даты (которая в настоящее время DATE_TEST: 03-NOV -2018) Так что все последние 7 дней будут проходить с 03-NOV-2018.

Предполагается:

DATE        DAY       Order
28-10-2018  SUN         1
29-10-2018  MON         2
30-10-2018  TUE         3
31-10-2018  WED         4
01-11-2018  THURS       5
02-11-2018  FRI         6
03-11-2018  SAT         7

Мы получили все 7 дней, упомянутых выше.

next_day (TO_DATE(DATE_TEST,'DD-MON-YY')-7,'FRIDAY') 

Теперь со следующего дня мы можем получить еще один день, и здесь мы просим пятницу, упоминая об этом в аргументе. Итак, пятница 02-11-2018.

Так что выходной будет 02-11-2018.

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