Hello,
Oracle version is Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production.
From the data below what I am trying to do is where the DATE field is empty, using the sequence number, find the closest record with a lower sequence number that has a DATE populated.
e.g so for sequence number 3 and 4 the selection matches to both records with a sequence number of 1 and 2 and because 2 is greater/closer returns the date 04/09/2016 10:19:51.
Unique id | DATE | Sequence number | Derived date |
---|
1 | 03/09/2016 10:19:51 | 1 | |
1 | 04/09/2016 10:19:51 | 2 | |
1 | NULL | 3 | 04/09/2016 10:19:51 |
1 | NULL | 4 | 04/09/2016 10:19:51 |
1 | 05/09/2016 10:19:51 | 5 | |
1 | NULL | 6 | 05/09/2016 10:19:51 |
I have written the following code but I wondered if there was anything simpler/more cost effective I could do..
WITH
data AS
(SELECT 1 unique_id, SYSDATE-10 notification_date, 1 sequence
FROM dual
UNION
SELECT 1 unique_id, SYSDATE-9 notification_date, 2 sequence
FROM dual
UNION
SELECT 1 unique_id, NULL notification_date, 3 sequence
FROM dual
UNION
SELECT 1 unique_id, NULL notification_date, 4 sequence
FROM dual
UNION
SELECT 1 unique_id, SYSDATE-8 notification_date, 5 sequence
FROM dual
UNION
SELECT 1 unique_id, NULL notification_date, 6 sequence
FROM dual),
derived_data AS
(SELECT DISTINCT d.unique_id,
d.sequence,
NVL(d.notification_date,
FIRST_VALUE(n.notification_date) OVER (PARTITION BY d.unique_id, d.sequence ORDER BY (d.sequence - n.sequence) ASC)) derived_date
FROM data d
LEFT OUTER JOIN data n ON n.unique_id = d.unique_id
AND n.sequence < d.sequence
AND n.notification_date IS NOT NULL
AND n.sequence IS NOT NULL)
SELECT *
FROM derived_data
ORDER BY 2
Cheers.