Найти первый и последний день последнего квартала в ORACLE
У меня есть запрос в форме:
select *
from X
where <some_date is in the last quarter>
У меня действительно проблемы с получением правильных дат за последний квартал. Итак, скажем, текущая дата - 1 июля, то есть в третьем квартале, я бы хотел, чтобы 1 апреля было ПЕРВЫМ, а 30 июня - ПОСЛЕДНИМ днем последнего квартала (т.е. второго квартала).
Немного погуглил и нашел тонны решений по этому вопросу, но каждый из них охватывал SQL Server, и доступные здесь фанк-методы недоступны в нашей базе данных ORACLE (Oracle 10g и 11g).
О да, а также мне нужно иметь возможность поместить все это в один запрос, так как это ограничение накладывает на меня какой-то инструмент, который будет дальше работать с этим запросом...:/
7 ответов
Это проще, но может быть не самым простым способом:
SELECT
ADD_MONTHS(TRUNC(SYSDATE, 'Q'), -3) AS First,
TRUNC(SYSDATE, 'Q') - 1 AS Last
FROM DUAL
Может быть, вы могли бы также использовать подобъект, чтобы исключить повторение кода:
SELECT
ADD_MONTHS(D, -3) AS First,
D - 1 AS Last
FROM (SELECT TRUNC(SYSDATE, 'Q') AS D FROM DUAL)
SELECT
TRUNC(SYSDATE, 'Q')AS FIRST_DAY,
last_day(add_months(TRUNC(SYSDATE, 'Q'),2)) as LAST_DAY
FROM DUAL;
Я знаю, что тема старая и закрытая, но так я правильно решил вопрос.
SELECT TRUNC(to_date('05.06.2020', 'dd.mm.yyyy'), 'Q') f_date,
LAST_DAY(ADD_MONTHS(TRUNC(TO_DATE('05.06.2020', 'dd.mm.yyyy'), 'Q'),2) ) l_date
FROM dual;
SELECT MIN (t), MAX (LAST_DAY (t))
FROM ( SELECT ADD_MONTHS (TRUNC (SYSDATE, 'yyyy'), LEVEL - 1) t,
TO_CHAR (ADD_MONTHS (TRUNC (SYSDATE, 'yyyy'), LEVEL - 1), 'Q')
r
FROM DUAL
CONNECT BY LEVEL <= 12) a
WHERE a.r = 4;
SELECT DATE_CURRENT
, TRUNC (ADD_MONTHS (DATE_CURRENT, -6), 'Q') AS FIRST
, LAST_DAY (TRUNC (ADD_MONTHS (DATE_CURRENT, -6), 'Q') + 85) AS LAST
, LAST_DAY (ADD_MONTHS(trunc(DATE_CURRENT,'Q'),-1)) AS PREVIOUS_QUARTER_END
, ADD_MONTHS(LAST_DAY (ADD_MONTHS(trunc(DATE_CURRENT,'Q'),-1)),-3)+1 AS PREVIOUS_QUARTER_START
FROM
(
SELECT TO_DATE ('31.07.2014', 'DD.MM.YYYY') AS DATE_CURRENT FROM DUAL
UNION SELECT TO_DATE ('30.06.2014', 'DD.MM.YYYY') AS DATE_CURRENT FROM DUAL
UNION SELECT TO_DATE ('30.04.2014', 'DD.MM.YYYY') AS DATE_CURRENT FROM DUAL
UNION SELECT TO_DATE ('31.03.2014', 'DD.MM.YYYY') AS DATE_CURRENT FROM DUAL
)
order by DATUM;
Как правило, как только я обращаюсь за помощью, я нахожу некоторый блог, который дает мне правильную идею, как продолжить.
Удалось собрать какое-то утверждение вместе, но оно абсолютно безобразно.:)
select
TRUNC(ADD_MONTHS(sysdate, -3),'Q') as first,
LAST_DAY(TRUNC(ADD_MONTHS(sysdate, -3),'Q')+ 85) as last
from dual;
Это работает, как кажется, однако, если кто-то знает о лучшем решении, пожалуйста, дайте мне знать! (to_date('27-JAN-11')
там в качестве примера дата...)
Изменить: Исправлена ошибка - добавление 3 месяцев к первому дню квартала не всегда заканчивается в том же квартале. Теперь это еще уродливее - чертовски григорианский календарь!
Это один из способов сделать это, он избавляет от необходимости определять первые и последние даты и помещает результаты в предложение where для вашего основного запроса:
select
*,
round(to_number(to_char(some_date, 'mm')) / 4) as quarter
from x
where round(to_number(to_char(some_date, 'mm')) / 4) = round(to_number(to_char(sysdate, 'mm')) / 4)
ВЫБЕРИТЕ DATE_CURRENT, TRUNC (DATE_CURRENT, 'Q'), как Q1F, LAST_DAY (ADD_MONTHS(TRUNC (DATE_CURRENT, 'Q'),2)), как Q1L, LAST_DAY (ADD_MONTHS (усечение (DATE_CURRENT))), QET, 1) AS Q2F, ADD_MONTHS(LAST_DAY (ADD_MONTHS(усечение (DATE_CURRENT,'Q'),-1)),-3)+1 AS Q2L, LAST_DAY (ADD_MONTHS(усечение (DATE_CURRENT,'Q'),-4)) AS Q3F, ADD_MONTHS(LAST_DAY (ADD_MONTHS(усечение (DATE_CURRENT,'Q'),-4)),-3)+1 AS Q3L, LAST_DAY (ADD_MONTHS(усечение (DATE_CURRENT,'Q'),-7)) AS Q4F, ADD_M (LAST_DAY (ADD_MONTHS (усечение (DATE_CURRENT,'Q'),-7)),-3)+1 AS Q4L, LAST_DAY (ADD_MONTHS(усечение (DATE_CURRENT,'Q'),-10)) AS Q5F, ADD_MONTHS(LAST_DAY (ADD_MONTHS(усечение (DATE_CURRENT,'Q'),-10)),-3)+1 AS Q5L, LAST_DAY (ADD_MONTHS(усечение (DATE_CURRENT,'Q'),-13)) AS Q6F, ADD_MONTHS(LAST_DON (LD_DON) (trunc(DATE_CURRENT,'Q'),-13)),-3)+1 AS Q6L, LAST_DAY (ADD_MONTHS(trunc(DATE_CURRENT,'Q'),-16)) AS Q7F, ADD_MONTHS(LAST_DAY (ADD_MONTHS(trunc(DATE_CURRENT,'Q'),-16)),-3)+1 AS Q7L, LAST_DAY (ADD_MONTHS(trunc(DATE_CURRENT,'Q'),-19)) AS Q8F, ADD_MONTHS(LAST_DAY (ADD_MONTHS(trunc(DATE_CURRENT,'Q'),-19)),-3)+1 AS Q8L FROM ( SELECT TO_DATE ('05.03.2017', 'DD.MM.YYYY') AS DATE_CURRENT FROM DUAL UNION SELECT TO_DATE ('30.06.2014', 'DD.MM.YYYY') КАК DATE_CURRENT ИЗ ДВОЙНОГО СОЮЗА ВЫБРАТЬ TO_DATE ('30.04.2014', 'DD.MM.YYYY') AS DATE_CURRENT ИЗ ДВОЙНОГО СОЮЗА ВЫБРАТЬ TO_DATE ('31.03.2014', ' ДД.ММ.ГГГГ ') AS DATE_CURRENT FROM DUAL)