sql >> Base de Datos >  >> RDS >> Oracle

Oracle SQL:obtenga la cantidad de días entre dos fechas para un mes específico

Febrero no es un mes, es el nombre genérico de un mes en un año. Un "mes" en el sentido correcto es febrero de 2016 o febrero de 2017, etc. Según el resultado deseado, supongo que se refiere a febrero de 2016.

El problema es trivial. Independientemente de cómo defina el mes, puede identificar el primer y el último día del mes. Por ejemplo, si ingresa el mes como una cadena de seis caracteres:input = '201602' , entonces puedes usar algo como

to_date(input, 'yyyymm')                as month_start, 
last_day(to_date(input, 'yyyymm'))      as month_end

y luego calcule el número de días como este:

Preparación (en SQLPlus):

SQL> variable input varchar2(30)
SQL> exec :input := '201602';

PL/SQL procedure successfully completed.

SQL> alter session set nls_date_format = 'dd/mm/yyyy';

Consulta :

with
     test_dates ( datefrom, dateto ) as (
       select to_date('28/1/2016', 'dd/mm/yyyy'), to_date('15/2/2016', 'dd/mm/yyyy') from dual union all
       select to_date('10/2/2016', 'dd/mm/yyyy'), to_date('3/3/2016' , 'dd/mm/yyyy') from dual union all
       select to_date('5/2/2016' , 'dd/mm/yyyy'), to_date('16/2/2016', 'dd/mm/yyyy') from dual union all
       select to_date('20/1/2016', 'dd/mm/yyyy'), to_date('10/3/2016', 'dd/mm/yyyy') from dual
     )
--  end of test data; solution (SQL query) begins below this line
select t.datefrom, t.dateto, to_char(to_date(:input, 'yyyymm'), 'MON yyyy') as month,
       case when t.datefrom > m.month_end or t.dateto < m.month_start then 0
            else least(t.dateto, m.month_end) - greatest(t.datefrom, m.month_start) + 1
            end as number_of_days
from   test_dates t cross join 
                  ( select to_date(:input, 'yyyymm') as month_start,
                           last_day(to_date(:input, 'yyyymm')) as month_end 
                    from   dual) m
;

Salida :(Nota:los números en su "salida deseada" son incorrectos)

DATEFROM   DATETO     MONTH    NUMBER_OF_DAYS
---------- ---------- -------- --------------
28/01/2016 15/02/2016 FEB 2016             15
10/02/2016 03/03/2016 FEB 2016             20
05/02/2016 16/02/2016 FEB 2016             12
20/01/2016 10/03/2016 FEB 2016             29

4 rows selected.