2011-09-08 82 views
5

Tengo una consulta de la forma:Buscar primero y último día del último trimestre en ORACLE

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

Realmente estoy teniendo problemas con la obtención de las fechas correctas para el último trimestre. Así, por ejemplo la fecha actual es primero de julio es decir, en el tercer trimestre, me gustaría obtener la primera de de abril de como primero y el 30a de de junio de como el último día de la último trimestre (es decir, el segundo trimestre).

Google buscó un montón y encontró toneladas de soluciones en esto, pero todos y cada uno de ellos cubrieron SQL Server y los métodos funky que están disponibles allí no están disponibles en nuestra base de datos ORACLE (Oracle 10g y 11g).

Oh sí, y también tengo que ser capaz de poner todo en una sola consulta, ya que es una restricción puesta sobre mí por alguna herramienta que va a seguir trabajando con esta consulta ...:/

Respuesta

11

Ésta es más sencillo , pero puede ser que no sea la forma más sencilla:

SELECT 
    ADD_MONTHS(TRUNC(SYSDATE, 'Q'), -3) AS First, 
    TRUNC(SYSDATE, 'Q') - 1 AS Last 
FROM DUAL 

Tal vez también se puede utilizar una subselección, de esta manera, para excluir alguna repetición de código:

SELECT 
    ADD_MONTHS(D, -3) AS First, 
    D - 1 AS Last 
FROM (SELECT TRUNC(SYSDATE, 'Q') AS D FROM DUAL) 
0

Típico, tan pronto como pido ayuda, encuentro un blog que me da la idea correcta de cómo proceder.

Se las arregló para noquear algunas afirmaciones, pero es absolutamente absurdo. :)

select 
    TRUNC(ADD_MONTHS(sysdate, -3),'Q') as first, 
    LAST_DAY(TRUNC(ADD_MONTHS(sysdate, -3),'Q')+ 85) as last 
from dual; 

Esto hace el truco como parece, sin embargo, si alguien sabe de una solución mejor, ¡por favor hágamelo saber! (to_date('27-JAN-11') está allí como una fecha de ejemplo ...)

Editar: Se corrigió un error: agregar 3 meses al primer día de un trimestre no siempre termina en el mismo trimestre. Ahora es incluso más feo, ¡maldito sea tu calendario gregoriano!

0

Esta es una manera de hacerlo, se ahorra la molestia de tener que trabajar en las primeras y últimas fechas y poner los resultados en una cláusula where para su búsqueda principal:

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) 
2
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
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; 
1
SELECT 
    TRUNC(SYSDATE, 'Q')AS FIRST_DAY, 
    last_day(add_months(TRUNC(SYSDATE, 'Q'),2)) as LAST_DAY     
FROM DUAL; 
0

SELECT DATE_CURRENT , TRUNC (DATE_CURRENT, 'Q') AS Q1F , LAST_DAY (ADD_MONTHS (TRUNC (DATE_CURRENT, 'Q'), 2)) AS Q1L , LAST_DAY (ADD_MONTHS (trunc (DATE_CURRENT, 'Q'), - 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)) AS Q4F , ADD_MONTHS (LAST_DAY (ADD_MONTHS (trunc (DATE_CURRENT, 'Q'), - 7)), - 3) +1 AS Q4L , LAST_DAY (ADD_MONTHS (trunc (DATE_CURRENT, 'Q'), - 10)) AS Q5F , ADD_MONTHS (LAST_DAY (ADD_MONTHS (trunc (DATE_CURRENT, 'Q'), - 10)), - 3) +1 AS Q5L , LAST_DAY (ADD_MONTHS (trunc (DATE_CURRENT, 'Q'), - 13)) AS Q6F , ADD_MONTHS (LAST_DAY (ADD_MONTHS (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 FRO M ( SELECT TO_DATE ('05 .03.2017' , 'DD.MM.AAAA') AS DATE_CURRENT FROM DUAL UNION SELECT TO_DATE ('30 .06.2014' , 'DD.MM.AAAA') AS DATE_CURRENT FROM DUAL UNION TO_DATE SELECT ('30 .04.2014' , 'DD.MM.AAAA') AS DATE_CURRENT DUAL DE UNION SELECT TO_DATE ('31 .03.2014' , 'DD.MM.AAAA') AS DATE_CURRENT FROM DUAL )

+0

favor edite su publicación para que el código esté formateado. Gracias. –

Cuestiones relacionadas