Home > database >  Calculating the days in a certain period
Calculating the days in a certain period

Time:11-11

I have a form which is connected to database, so this form can have more blocks, where each block have date from, date until for example

Block Date_From Date_until
1 25.07.2022 11.08.2022
2 05.08.2022 15.08.2022
3 10.08.2022 20.08.2022
4 11.08.2022 05.09.2022

I'm trying to make a SELECT statement which going to display number of days between 01.08.2022 and 31.08.2022.

  • first block date_from = 25.07.2022, date_until = 11.08.2022 ->11 days
  • second block and third block should remain NULL or some default text, because the interval of these blocks is in fourth block.
  • fourth block date_from = 11.08.2022, date_until = 05.09.2022-> 20 days (until the end of the month).

Could you help me guys with creating this select? The select should have date_from, date_until and number of days.

CodePudding user response:

WITH data(Block,Date_From,Date_until) AS (
    SELECT 1, TO_DATE('25.07.2022','DD.MM.YYYY'), TO_DATE('11.08.2022','DD.MM.YYYY') FROM DUAL UNION ALL
    SELECT 2, TO_DATE('05.08.2022','DD.MM.YYYY'), TO_DATE('15.08.2022','DD.MM.YYYY') FROM DUAL UNION ALL
    SELECT 3, TO_DATE('10.08.2022','DD.MM.YYYY'), TO_DATE('20.08.2022','DD.MM.YYYY') FROM DUAL UNION ALL
    SELECT 4, TO_DATE('11.08.2022','DD.MM.YYYY'), TO_DATE('05.09.2022','DD.MM.YYYY') FROM DUAL -- UNION ALL
),
clipped(Block,Date_From,Date_until) AS (
    SELECT Block, GREATEST(Date_From, TO_DATE('01.08.2022','DD.MM.YYYY')), LEAST(Date_until, TO_DATE('31.08.2022','DD.MM.YYYY')) FROM DATA
)
SELECT c.*, 
    CASE WHEN NOT(
        EXISTS(SELECT 1 FROM clipped d WHERE d.Date_From < c.Date_until AND d.Date_until > c.Date_From AND d.block < c.block) 
        AND
        EXISTS(SELECT 1 FROM clipped d WHERE d.Date_From < c.Date_until AND d.Date_until > c.Date_From AND d.block > c.block) )
        THEN c.Date_until - c.Date_from  ELSE NULL
    END AS days
FROM clipped c
ORDER BY c.block 
;


1   01/08/22    11/08/22    10
2   05/08/22    15/08/22    
3   10/08/22    20/08/22    
4   11/08/22    31/08/22    20
  • Related