简体   繁体   中英

PL/SQL Finding Difference Between Start and End Dates in Different Rows

I am trying to find the difference between start and end dates in different rows of a result set, using PL/SQL. Here is an example:

ID    TERM    START_DATE  END_DATE

423   201420    26-AUG-13   13-DEC-13

423   201430    21-JAN-14   09-MAY-14

423   201440    16-JUN-14   07-AUG-14

For any specific ID, I need to get the difference between the end date in the first record and the start date of the second record. Similarly, I need to get the difference between the end date in the second record and the start date of the third record, and so forth.
Eventually I will need to perform the same operation on a variety of IDs. I am assuming I have to use a cursor and loop.

I would appreciate any help or suggestions on accomplishing this. Thanks in advance.

The "lead" analytic function in Oracle can grab a value from the succeeding row as a value in the current row.

Given a series of rows returned from a query and a position of the cursor, LEAD provides access to a row at a given physical offset beyond that position.

Here, this SQL grabs start_date from the next row and subtracts end_date from the current row.

select id, term, start_date, end_date,
       lead(start_date) over (partition by id order by term) - end_date diff_in_days
from your_table;

Sample output:

        ID TERM       START_DATE           END_DATE             DIFF_IN_DAYS
---------- ---------- -------------------- -------------------- ------------
       423 201420     26-AUG-2013 00:00:00 13-DEC-2013 00:00:00           39
       423 201430     21-JAN-2014 00:00:00 09-MAY-2014 00:00:00           36
       423 201440     14-JUN-2014 00:00:00 07-AUG-2014 00:00:00

I would suggest looking at using the LEAD and LAG analytic functions from Oracle. By the sounds of it they should suit your needs.

See the docs here: http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions074.htm

Code:

SELECT [ID], [TERM], [START_DATE], [END_DATE],
       CASE WHEN MIN([END_DATE]) OVER(PARTITION BY [ID] ORDER BY [TERM] ROWS BETWEEN 1 PRECEDING AND CURRENT ROW)=[END_DATE] THEN NULL ELSE
       MIN([END_DATE]) OVER(PARTITION BY [ID] ORDER BY [TERM] ROWS BETWEEN 1 PRECEDING AND CURRENT ROW)-[START_DATE] END AS [DAYS_BETWEEN]
FROM [TABLE]

这似乎可行:

SELECT DISTINCT ID, TERM_CODE, TERM_START_DATE, TERM_END_DATE, ( ( LEAD ( TERM_START_DATE, 1 ) OVER ( PARTITION BY ID ORDER BY TERM_CODE ) ) -TERM_END_DATE AS DIFF DAYS FROM TABLE

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM