oracle sql получить в прошлое воскресенье и в прошлую субботу

Я буду рассчитывать последнее воскресенье и последнюю субботу на каждый понедельник.

Например. сегодня 08 июля 2013 понедельник

прошлое воскресенье: 30 июня 2013 г. 00:00:00

прошлая суббота: 6 июля 2013 г. 23:59:59.

Обратите внимание, что последнее воскресенье — с 00:00:00, а последняя суббота — до 23:59:59.


person thotwielder    schedule 08.07.2013    source источник
comment
возможный дубликат Поиск дня недели в оракуле   -  person Jon Heller    schedule 08.07.2013
comment
Почему последнее воскресенье неделю назад, а последнее воскресенье позавчера? Это не имеет смысла.   -  person a_horse_with_no_name    schedule 09.07.2013
comment
@a_horse_with_no_name это потому, что здесь (в этой компании) воскресенье первый день недели, а суббота последний день недели. Итак, в понедельник, который на самом деле является вторым днем ​​недели. Таким образом, между «прошлым воскресеньем» и «прошлой субботой» будет 5 дней.   -  person thotwielder    schedule 09.07.2013


Ответы (5)


Учитывая ваш вопрос, где запрос будет выполняться только по понедельникам, а цель состоит в том, чтобы получить даты, как указано выше, один из способов его решения:

SELECT TRUNC(SYSDATE) AS TODAYS_DATE,
       TRUNC(SYSDATE)-8 AS PREVIOUS_SUNDAY,
       TRUNC(SYSDATE) - (INTERVAL '1' DAY + INTERVAL '1' SECOND) AS PREVIOUS_SATURDAY
  FROM DUAL

Делитесь и наслаждайтесь.

person Bob Jarvis - Reinstate Monica    schedule 09.07.2013

Для тех, кто хочет получить последние выходные дни (субботу и воскресенье) на неделе, где первый день — понедельник, вот альтернатива:

select today as todays_date,
       next_day(today - 7, 'sat') as prev_saturday, 
       next_day(today - 7, 'sun') as prev_sunday
from dual
person Max    schedule 01.09.2014
comment
Нашему Oracle не понравилось «сегодня», поэтому я заменил «sysdate» и получил ожидаемый результат — спасибо, что научили меня функции «next_day»! - person Kendall Lister; 30.11.2017

Запрос на получение последнего ВОСКРЕСЕНЬЯ:

SELECT TRUNC(SYSDATE)-(select to_char(sysdate-1, 'd') FROM DUAL) FROM DUAL

Запрос на получение последней субботы:

SELECT TRUNC(SYSDATE)-(select to_char(sysdate, 'd') from dual) FROM DUAL

Если вы хотите получить предыдущее ВОСКРЕСЕНЬЕ/СУББОТУ, вам нужно добавить в sysdate, например:

Предыдущее воскресенье:

SELECT TRUNC(SYSDATE)-(select to_char(sysdate, 'd')+6 FROM DUAL) FROM DUAL

Предыдущая суббота:

SELECT TRUNC(SYSDATE)-(select to_char(sysdate, 'd')+7 FROM DUAL) FROM DUAL

Преимущество этого подхода заключается в том, что вы можете выполнять этот запрос каждый день недели.

person majcher_zlo    schedule 31.08.2016
comment
Хороший. Но ПОСЛЕДНЕЕ ВОСКРЕСЕНЬЕ должно быть с to_number(to_char(sysdate-1,'d'), ПОСЛЕДНЯЯ СУББОТА с to_number(to_char(sysdate,'d') - person Alisson Gomes; 16.08.2019
comment
это дает предыдущее воскресенье, если я запускаю его в воскресенье. - person Jef; 19.11.2020
comment
Вложенный двойной не нужен. это может быть, как указано ниже, SELECT TRUNC(SYSDATE)-to_char(sysdate-1, 'd') FROM DUAL для воскресенья и аналогично для субботы. - person born_naked; 28.06.2021

Вот самый быстрый способ получить последнюю субботу или последнее воскресенье из ЛЮБОГО дня недели:

Прошлая суббота:

select trunc(SYSDATE) - to_char(sysdate, 'd')  from dual;

Прошлое воскресенье:

select trunc(SYSDATE) - (to_char(sysdate, 'd')-1)  from dual;

Извиняюсь за то, что потратил 6 лет на то, чтобы дать вам лучший ответ. ;)

person Aj M.    schedule 09.07.2019

Используйте следующую функцию PLSQL, чтобы получить DayDate недели.

Использование функции для получения дня месяца.

SELECT
 DayofMonth(to_date('2020-03-29T01:00Z', 'yyyy-mm-dd"T"hh24:mi"Z"'), 'FRI', 'LAST') LASTFRI    -- 27-MAR-2020 01:00:00
 ,DayofMonth(to_date('2020-03-29T01:00Z', 'yyyy-mm-dd"T"hh24:mi"Z"'), 'SUN', 'FIRST') FIRSTSUN -- 01-MAR-2020 01:00:00
 ,DayofMonth(to_date('2020-03-29T01:00Z', 'yyyy-mm-dd"T"hh24:mi"Z"'), 'SUN', 'THIRD') THIRDSUN -- 15-MAR-2020 01:00:00
 
 ,DayofMonth(to_date('2020-02-02T01:01Z', 'yyyy-mm-dd"T"hh24:mi"Z"'), 'SUN', 'THIRD') THIRDSUN_FEB29  -- 16-FEB-2020 01:01:00
 ,DayofMonth(to_date('2021-02-02T01:01Z', 'yyyy-mm-dd"T"hh24:mi"Z"'), 'SUN', 'FOURTH') FouthSUN_FEB28 -- 28-FEB-2021 01:01:00
from dual;

PLSQL-функция: приведенная ниже функция, определяющая последний день месяца, преобразуется в число, используя TO_NUMBER() для передачи в качестве параметра LAST_DAY().

create or replace FUNCTION DayofMonth 
(dateOfMonth in date, dayOfWeek in varchar2 default 'SUN', weekOfMonth in varchar2 default 'LAST')
return date AS date_out date;

firstDayOfMonth number(5); lastDayOfMonth number(5);
monthFirstDayDate date; monthSecondDayDate date;
monthThirdDayDate date; monthFourthDayDate date;
monthLastDayDate date;
BEGIN

  SELECT TO_NUMBER(to_char( trunc(dateOfMonth) - (to_number(to_char(dateOfMonth,'DD')) - 1), 'DD'), '9G999D99') into firstDayOfMonth FROM dual;
  SELECT TO_NUMBER(to_char(trunc( add_months(trunc(dateOfMonth) - (to_number(to_char(dateOfMonth,'DD')) - 1), 1) -1 ), 'DD'), '9G999D99') into lastDayOfMonth FROM dual;
DBMS_OUTPUT.put_line('firstDayOfMonth:' || firstDayOfMonth || ', lastDayOfMonth:' || lastDayOfMonth);

select next_day(LAST_DAY(dateOfMonth) - (lastDayOfMonth - (7 * 0)), dayOfWeek) into monthFirstDayDate   FROM DUAL;
select next_day(LAST_DAY(dateOfMonth) - (lastDayOfMonth - (7 * 1)), dayOfWeek) into monthSecondDayDate  FROM DUAL;
select next_day(LAST_DAY(dateOfMonth) - (lastDayOfMonth - (7 * 2)), dayOfWeek) into monthThirdDayDate   FROM DUAL;
select next_day(LAST_DAY(dateOfMonth) - (lastDayOfMonth - (7 * 3)), dayOfWeek) into monthFourthDayDate  FROM DUAL;
select next_day(LAST_DAY(dateOfMonth) - (7),                        dayOfWeek) into monthLastDayDate    FROM DUAL;

DBMS_OUTPUT.put_line('monthFirstDayDate:'  || monthFirstDayDate || ', monthSecondDayDate:' || monthSecondDayDate);
DBMS_OUTPUT.put_line('monthThirdDayDate:'  || monthThirdDayDate || ', monthFourthDayDate:' || monthFourthDayDate);
DBMS_OUTPUT.put_line('monthLastDayDate:'   || monthLastDayDate);

IF (weekOfMonth = 'LAST') then
  date_out := monthLastDayDate;
ELSIF (weekOfMonth = 'FIRST') then
  date_out := monthFirstDayDate;
ELSIF (weekOfMonth = 'SECOND') then
  date_out := monthSecondDayDate;
ELSIF (weekOfMonth = 'THIRD') then
  date_out := monthThirdDayDate;
ELSIF (weekOfMonth = 'FOURTH') then
  date_out := monthFourthDayDate;
ELSE
  date_out := null;
END IF;

    return date_out;
EXCEPTION
    when others then
        DBMS_OUTPUT.put_line('Date:' || dateOfMonth || ', Day:' || dayOfWeek || ', Week:' || weekOfMonth || ' / ' || sqlcode || ' / ' || SQLERRM(sqlcode));
        date_out := null;
        return date_out;
END;
/

Первый и последний день месяца — Oracle SQL

SELECT
  to_char( trunc(sysdate) - (to_number(to_char(sysdate,'DD')) - 1), 'DD') as firstDay
  ,to_char(trunc( add_months(trunc(sysdate) - (to_number(to_char(sysdate,'DD')) - 1), 1) -1 ), 'DD') as lastDay
FROM dual;

Тесты для проверки дня месяца без какой-либо функции:

select
    next_day(LAST_DAY(to_date('2021-01-29T01:01Z', 'yyyy-mm-dd"T"hh24:mi"Z"')) - 7, 'sun') as JAN_Month_Last_SUNDAY31 -- 31-JAN-2021 01:01:00
    ,next_day(LAST_DAY(to_date('2021-02-01T01:01Z', 'yyyy-mm-dd"T"hh24:mi"Z"')) - 7, 'sun') as FEB_Month_Last_SUNDAY28 -- 28-FEB-2021 01:01:00
    ,next_day(LAST_DAY(to_date('2021-04-01T01:01Z', 'yyyy-mm-dd"T"hh24:mi"Z"')) - 7, 'sun') as APRL_Month_Last_SUNDAY30 -- 25-APR-2021 01:01:00
    
    ,next_day(LAST_DAY(to_date('2021-01-29T01:01Z', 'yyyy-mm-dd"T"hh24:mi"Z"')) - 31, 'sun') as JAN_Month_First_SUNDAY31 -- 31-JAN-2021 01:01:00
    ,next_day(LAST_DAY(to_date('2021-02-01T01:01Z', 'yyyy-mm-dd"T"hh24:mi"Z"')) - 28, 'sun') as FEB_Month_First_SUNDAY28 -- 28-FEB-2021 01:01:00
    ,next_day(LAST_DAY(to_date('2021-04-01T01:01Z', 'yyyy-mm-dd"T"hh24:mi"Z"')) - 30, 'sun') as APRL_Month_First_SUNDAY30 -- 25-APR-2021 01:01:00
FROM DUAL;

select
  next_day(LAST_DAY(to_date('2021-01-29T01:01Z', 'yyyy-mm-dd"T"hh24:mi"Z"')) - 7, 'mon') as JAN_Month_Last_Mon31
  ,next_day(LAST_DAY(to_date('2021-01-29T01:01Z', 'yyyy-mm-dd"T"hh24:mi"Z"')) - 7, 'fri') as JAN_Month_Last_Fri31
  ,next_day(LAST_DAY(to_date('2021-01-29T01:01Z', 'yyyy-mm-dd"T"hh24:mi"Z"')) - (31 - (7 * 0)), 'fri') as JAN_Month_First_Fri31
  ,next_day(LAST_DAY(to_date('2021-01-29T01:01Z', 'yyyy-mm-dd"T"hh24:mi"Z"')) - (31 - (7 * 1)), 'fri') as JAN_Month_Second_Fri31
  ,next_day(LAST_DAY(to_date('2021-01-29T01:01Z', 'yyyy-mm-dd"T"hh24:mi"Z"')) - (31 - (7 * 2)), 'fri') as JAN_Month_Third_Fri31
  ,next_day(LAST_DAY(to_date('2021-01-29T01:01Z', 'yyyy-mm-dd"T"hh24:mi"Z"')) - (31 - (7 * 3)), 'fri') as JAN_Month_Fourth_Fri31
  ,next_day(LAST_DAY(to_date('2021-01-29T01:01Z', 'yyyy-mm-dd"T"hh24:mi"Z"')) - (31), 'fri') as JAN_Month_Last_Fri31
FROM DUAL;

select
  next_day(LAST_DAY(to_date('2021-02-02T01:01Z', 'yyyy-mm-dd"T"hh24:mi"Z"')) - (28 - (7 * 0)), 'fri') as FEB_Month_First_Fri28
  ,next_day(LAST_DAY(to_date('2021-02-02T01:01Z', 'yyyy-mm-dd"T"hh24:mi"Z"')) - (28 - (7 * 1)), 'fri') as FEB_Month_Second_Fri28
  ,next_day(LAST_DAY(to_date('2021-02-02T01:01Z', 'yyyy-mm-dd"T"hh24:mi"Z"')) - (28 - (7 * 2)), 'fri') as FEB_Month_Third_Fri28
  ,next_day(LAST_DAY(to_date('2021-02-02T01:01Z', 'yyyy-mm-dd"T"hh24:mi"Z"')) - (28 - (7 * 3)), 'SUN') as FEB_Month_Fourth_Fri28
  ,next_day(LAST_DAY(to_date('2021-02-02T01:01Z', 'yyyy-mm-dd"T"hh24:mi"Z"')) - (7), 'fri') as FEB_Month_Last_Fri28
FROM DUAL;

select
  next_day(LAST_DAY(to_date('2020-02-02T01:01Z', 'yyyy-mm-dd"T"hh24:mi"Z"')) - (29 - (7 * 0)), 'fri') as FEB_Month_First_Fri29
  ,next_day(LAST_DAY(to_date('2020-02-02T01:01Z', 'yyyy-mm-dd"T"hh24:mi"Z"')) - (29 - (7 * 1)), 'fri') as FEB_Month_Second_Fri29
  ,next_day(LAST_DAY(to_date('2020-02-02T01:01Z', 'yyyy-mm-dd"T"hh24:mi"Z"')) - (29 - (7 * 2)), 'fri') as FEB_Month_Third_Fri29
  ,next_day(LAST_DAY(to_date('2020-02-02T01:01Z', 'yyyy-mm-dd"T"hh24:mi"Z"')) - (29 - (7 * 3)), 'fri') as FEB_Month_Fourth_Fri29
  ,next_day(LAST_DAY(to_date('2020-02-02T01:01Z', 'yyyy-mm-dd"T"hh24:mi"Z"')) - (7), 'fri') as FEB_Month_Last_Fri29
FROM DUAL;
person Yash    schedule 22.12.2020