Найти первый и последний день последнего квартала в ORACLE - PullRequest
6 голосов
/ 08 сентября 2011

У меня есть запрос в форме:

select *
from X
where <some_date is in the last quarter>

У меня действительно проблемы с получением правильных дат за последний квартал.Итак, скажем, текущая дата 1 июля , т.е. в третьем квартале я бы хотел получить 1 апреля как ПЕРВЫЙ и 30 июня как последний день последнего квартала (т. е. второго квартала).

Немного погуглил и нашел тонны решений по этому вопросу, но каждый из них охватывал SQL Serverдоступные здесь фанк-методы недоступны в нашей базе данных ORACLE (Oracle 10g и 11g).

О да, а также мне нужно иметь возможность поместить все это в один запрос, так как этоограничение, наложенное на меня каким-то инструментом, который в дальнейшем будет работать с этим запросом ...: /

Ответы [ 7 ]

12 голосов
/ 08 сентября 2011

Это проще, но все же может быть не самым простым способом:

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)
3 голосов
/ 09 августа 2016
SELECT
  TRUNC(SYSDATE, 'Q')AS FIRST_DAY,
  last_day(add_months(TRUNC(SYSDATE, 'Q'),2)) as LAST_DAY                
FROM DUAL;
1 голос
/ 25 июля 2012
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;
0 голосов
/ 05 марта 2017

ВЫБРАТЬ DATE_CURRENT, TRUNC (DATE_CURRENT, 'Q') AS Q1F, LAST_DAY (ADD_MONTHS (TRUNC (DATE_CURRENT, 'Q'), 2)) AS Q1L, LAST_DAY (ADD_MONTHS (усечение (DATE_CURT))1)) AS Q2F, ADD_MONTHS (LAST_DAY (ADD_MONTHS (trunc (DATE_CURRENT, 'Q'), - 1)), - 3) +1 AS Q2L, LAST_DAY (ADD_MONTHS (trunc (DATE_CURRENT, 'Q')), - 4)) AS Q3F, ADD_MONTHS (LAST_DAY (ADD_MONTHS (trunc (DATE_CURRENT, 'Q'), - 4)), - 3) +1 AS Q3L, LAST_DAY (ADD_MONTHS (trunc (DATE_CURRENT, 'Q'), - 7)) ASQ4F, ADD_MONTHS (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_MONLAST_DAY (ADD_MONTHS (усечение (DATE_CURRENT, 'Q'), - 13)), - 3) +1 AS Q6L, LAST_DAY (ADD_MONTHS (усечение (DATE_CURRENT, 'Q'), - 16)) AS Q7F, ADD_MONTHS (LAST_DAY (LAST_DAYADD_MONTHS (усечение (DATE_CURRENT, 'Q'), - 16)), - 3) +1 AS Q7L, LAST_DAY (ADD_MONTHS (усечение (DATE_CURRENT, 'Q'), - 19)) AS Q8F, ADD_MONTHS (LAST_DAY (ADD_MONTHS (усечение (DATE_CURRENT, 'Q'), - 19)), - 3) +1 AS Q8L FROM (ВЫБРАТЬ TO_DATE ('05 .03.2017 ',' DD.MM.YYYY ') AS DATE_CURRENT FROM DUALUNION 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)

0 голосов
/ 22 августа 2014
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;
0 голосов
/ 08 сентября 2011

Это один из способов сделать это, он избавляет от необходимости определять первые и последние даты и помещает результаты в предложение 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)
0 голосов
/ 08 сентября 2011

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

Удалось собрать какое-то утверждение вместе, однако оно абсолютно бездарнонекрасиво.:)

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 месяцев к первому дню квартала не всегда заканчивалось в одном квартале.Теперь это еще уродливее - чертовски григорианский календарь!

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