Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Oracle SQL - obtenha o número de dias entre duas datas para um mês especificado


Fevereiro não é um mês, é o nome genérico de um mês em um ano. Um "mês" no sentido apropriado é fevereiro de 2016 ou fevereiro de 2017 etc. Com base na saída desejada, suponho que você queira dizer fevereiro de 2016.

O problema é banal. Independentemente de como você define o mês, você pode identificar o primeiro e o último dia do mês. Por exemplo, se você inserir o mês como uma string de seis caracteres:input = '201602' , então você pode usar algo como
to_date(input, 'yyyymm')                as month_start, 
last_day(to_date(input, 'yyyymm'))      as month_end

e, em seguida, calcule o número de dias assim:

Preparação (no SQL Plus):
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
;

Saída :(Nota:os números em sua "saída desejada" estão incorretos)
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.