#sql #oracle #date #plsql
Вопрос:
У меня есть требование, согласно которому я должен выбирать данные из БД на основе переданных в нее данных start_date и end_date.
- Если sysdate-воскресенье, то функция должна возвращать start_date как дату в субботу в формате YYYYMMDD и end_date как дату в субботу в формате YYYYMMDD.
- Если sysdate-понедельник, то дата начала должна быть датой в субботу, а дата окончания-в воскресенье.
- Если sysdate-вторник, то дата начала должна быть датой субботы, а дата окончания-понедельника … и так далее..
Как будет выглядеть функция, возвращающая две даты в формате YYYYMMDD на основе req.
Комментарии:
1. Я не совсем понимаю, что вы пытаетесь сделать, сначала вы говорите, что функции нужны два входных данных: start_date и end_date, а затем вы говорите, чтобы вернуть две даты с условиями, основанными на текущей дате. Вы хотите, чтобы функция возвращала дату начала и дату окончания, измененные на другие даты в зависимости от текущей даты? Или вы хотите рассчитать дату начала и дату окончания только на основе текущей даты, и вы не передаете функции никаких дат в качестве входных данных?
2. Следуя моему предыдущему комментарию, если вы пытаетесь использовать первый вариант, о котором я говорил ранее, какую дату вы хотите в качестве вывода для своих данных, ту же дату или ближайшую предыдущую субботу для даты начала, например, если дата начала 2021/11/18 (четверг) в качестве вывода для даты начала вы хотите 20211113 или следующую доступную субботу: 20211120 в моем примере. Что произойдет, если дата начала-суббота (2021/11/13), а текущая дата-суббота? Аналогичные вопросы для end_date.
3. Пожалуйста, проясните вашу конкретную проблему или предоставьте дополнительные сведения, чтобы выделить именно то, что вам нужно. Поскольку это написано в настоящее время, трудно точно сказать, о чем вы просите.
Ответ №1:
Похоже, что дата начала всегда суббота, в то время как дата окончания-день, предшествующий дате sysdate.
Если это так, то вот как:
Моя база данных говорит по-хорватски, поэтому я переключаюсь на английский (и устанавливаю формат даты по умолчанию, просто чтобы показать, что такое sysdate); вам не нужно этого делать.
SQLgt; alter session set nls_date_language = 'english'; Session altered. SQLgt; alter session set nls_date_format = 'dd.mm.yyyy'; Session altered.
TEMP
CTE имитирует изменение sysdate. next_day
функция выполняет поиск по субботе, предшествующей sysdate
.
21.11.2021-воскресенье, поэтому вы хотите получить 20.11.2021 в качестве даты начала и окончания:
SQLgt; with temp as (select date '2021-11-21' sys_date from dual) 2 select 3 sys_date, 4 to_char(next_day(sys_date, 'SATURDAY') - 7, 'yyyymmdd') as start_date, 5 to_char(sys_date - 1, 'yyyymmdd') as end_date 6 from temp; SYS_DATE START_DA END_DATE ---------- -------- -------- 21.11.2021 20211120 20211120
23.11.2021 — вторник, поэтому вы хотите, чтобы суббота была датой начала, а понедельник-датой окончания:
SQLgt; with temp as (select date '2021-11-23' sys_date from dual) 2 select 3 sys_date, 4 to_char(next_day(sys_date, 'SATURDAY') - 7, 'yyyymmdd') as start_date, 5 to_char(sys_date - 1, 'yyyymmdd') as end_date 6 from temp; SYS_DATE START_DA END_DATE ---------- -------- -------- 23.11.2021 20211120 20211122 SQLgt;
На самом деле, вы бы просто
SQLgt; select 2 sysdate, 3 to_char(next_day(sysdate, 'SATURDAY') - 7, 'yyyymmdd') as start_date, 4 to_char(sysdate - 1, 'yyyymmdd') as end_date 5 from dual; SYSDATE START_DA END_DATE ---------- -------- -------- 18.11.2021 20211113 20211117 SQLgt;