Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Counting difference of two dates in a PL SQL FUNCTION, should be returing number of days

I have the following output:

from_date until_date
17.03.2020 18.05.2020
18.05.2020 08.06.2020
21.12.2020 01.03.2021
01.03.2021 11.03.2021
19.10.2021 22.10.2021
10.01.2022 14.01.2022
14.01.2022 NULL

I need to count the days between these two dates, second date inclusively, with this logic:

(18.05.2020 -  17.03.2020)+1 = 63

The next row begins at the same day as it ends in the first row,
then the 18.05.2020 must not be counted in the days difference, so:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

08.06.2020 - 18.05.2020

if the until_date is null then it will be:

sysdate-from_date

but what im struggling to do is to get next element and previous element values in a loop so I can compare them

>Solution :

You can use the LAG analytic function to find the previous until_date:

SELECT from_date,
       until_date,
       COALESCE(until_date, TRUNC(SYSDATE)) - from_date
         + CASE
           WHEN LAG(until_date) OVER (ORDER BY FROM_DATE) = from_date
           THEN 0
           ELSE 1
           END
         AS difference
FROM   table_name;

Which, for the sample data:

CREATE TABLE table_name (from_date, until_date) AS
SELECT DATE '2020-03-17', DATE '2020-05-18' FROM DUAL UNION ALL
SELECT DATE '2020-05-18', DATE '2020-06-08' FROM DUAL UNION ALL
SELECT DATE '2020-12-21', DATE '2021-03-01' FROM DUAL UNION ALL
SELECT DATE '2021-03-01', DATE '2021-03-11' FROM DUAL UNION ALL
SELECT DATE '2021-10-19', DATE '2021-10-22' FROM DUAL UNION ALL
SELECT DATE '2022-01-10', DATE '2022-01-14' FROM DUAL UNION ALL
SELECT DATE '2022-01-14', NULL FROM DUAL;

Outputs:

FROM_DATE UNTIL_DATE DIFFERENCE
2020-03-17 00:00:00 2020-05-18 00:00:00 63
2020-05-18 00:00:00 2020-06-08 00:00:00 21
2020-12-21 00:00:00 2021-03-01 00:00:00 71
2021-03-01 00:00:00 2021-03-11 00:00:00 10
2021-10-19 00:00:00 2021-10-22 00:00:00 4
2022-01-10 00:00:00 2022-01-14 00:00:00 5
2022-01-14 00:00:00 null 154

If you want it in PL/SQL then wrap the query in a cursor and loop through the cursor in PL/SQL.

BEGIN
  FOR r IN (
    SELECT from_date,
           until_date,
           COALESCE(until_date, TRUNC(SYSDATE)) - from_date
             + CASE
               WHEN LAG(until_date) OVER (ORDER BY FROM_DATE) = from_date
               THEN 0
               ELSE 1
               END
             AS difference
    FROM   table_name
  ) LOOP
    DBMS_OUTPUT.PUT_LINE( r.from_date || ', ' || r.until_date || ', ' || r.difference );
  END LOOP;
END;
/

Or you can do exactly the same thing by storing the previous until_date in a PL/SQL variable:

DECLARE
  v_until_date DATE;
  v_diff       NUMBER;
BEGIN
  FOR r IN (
    SELECT from_date,
           until_date
    FROM   table_name
    ORDER BY from_date
  ) LOOP
    v_diff := COALESCE(r.until_date, TRUNC(SYSDATE)) - r.from_date
            + CASE WHEN v_until_date = r.from_date THEN 0 ELSE 1 END;
    DBMS_OUTPUT.PUT_LINE(
      r.from_date
      || ', ' || r.until_date
      || ', ' || v_diff
    );
    v_until_date := r.until_date;
  END LOOP;
END;
/

db<>fiddle here

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading