I have a table called road_events
.
create table road_events
(
event_id number(5,0),
road_id number(5,0),
event_type nvarchar2(50),
lifecycle_number number(5,0)
);
insert into road_events (event_id,road_id,event_type,lifecycle_number) values (1,100,'RECONSTRUCTION',1);
insert into road_events (event_id,road_id,event_type,lifecycle_number) values (2,100,'RECONSTRUCTION',2);
insert into road_events (event_id,road_id,event_type,lifecycle_number) values (3,100,'INSPECTION',2);
insert into road_events (event_id,road_id,event_type,lifecycle_number) values (4,100,'INSPECTION',2);
insert into road_events (event_id,road_id,event_type,lifecycle_number) values (5,100,'INSPECTION',2);
insert into road_events (event_id,road_id,event_type,lifecycle_number) values (6,100,'INSPECTION',2);
insert into road_events (event_id,road_id,event_type,lifecycle_number) values (7,200,'INSPECTION',0);
insert into road_events (event_id,road_id,event_type,lifecycle_number) values (8,200,'RECONSTRUCTION',1);
insert into road_events (event_id,road_id,event_type,lifecycle_number) values (9,200,'INSPECTION',1);
insert into road_events (event_id,road_id,event_type,lifecycle_number) values (10,200,'INSPECTION',1);
insert into road_events (event_id,road_id,event_type,lifecycle_number) values (11,200,'RECONSTRUCTION',2);
insert into road_events (event_id,road_id,event_type,lifecycle_number) values (12,200,'INSPECTION',2);
insert into road_events (event_id,road_id,event_type,lifecycle_number) values (13,200,'INSPECTION',2);
insert into road_events (event_id,road_id,event_type,lifecycle_number) values (14,200,'INSPECTION',2);
insert into road_events (event_id,road_id,event_type,lifecycle_number) values (15,200,'RECONSTRUCTION',3);
insert into road_events (event_id,road_id,event_type,lifecycle_number) values (16,300,'RECONSTRUCTION',1);
insert into road_events (event_id,road_id,event_type,lifecycle_number) values (17,400,'INSPECTION',0);
insert into road_events (event_id,road_id,event_type,lifecycle_number) values (18,500,'RECONSTRUCTION',1);
insert into road_events (event_id,road_id,event_type,lifecycle_number) values (19,500,'RECONSTRUCTION',2);
insert into road_events (event_id,road_id,event_type,lifecycle_number) values (20,600,'INSPECTION',0);
insert into road_events (event_id,road_id,event_type,lifecycle_number) values (21,600,'INSPECTION',0);
select
event_id,
road_id,
substr(event_type,0,15) as event_type,
lifecycle_number
from
road_events
order by
event_id
EVENT_ID ROAD_ID EVENT_TYPE LIFECYCLE_NUMBER
---------- ---------- --------------- ----------------
1 100 RECONSTRUCTION 1
2 100 RECONSTRUCTION 2
3 100 INSPECTION 2
4 100 INSPECTION 2
5 100 INSPECTION 2
6 100 INSPECTION 2
7 200 INSPECTION 0
8 200 RECONSTRUCTION 1
9 200 INSPECTION 1
10 200 INSPECTION 1
11 200 RECONSTRUCTION 2
12 200 INSPECTION 2
13 200 INSPECTION 2
14 200 INSPECTION 2
15 200 RECONSTRUCTION 3
16 300 RECONSTRUCTION 1
17 400 INSPECTION 0
18 500 RECONSTRUCTION 1
19 500 RECONSTRUCTION 2
20 600 INSPECTION 0
21 600 INSPECTION 0
For each road, I would like to categorize the rows in each lifecycle with a lifecycle_name
(in this order):
- The rows in the last(max) lifecycle would be called
current lifecycle
- The rows in the first(min) lifecycle would be called
original lifecycle
(if applicable) - Any others would be called
past lifecycle
(if applicable)
It would look like this:
+----------+---------+----------------+------------------+--------------------+
| EVENT_ID | ROAD_ID | EVENT_TYPE | LIFECYCLE_NUMBER | LIFECYCLE_NAME |
+----------+---------+----------------+------------------+--------------------+
| 1 | 100 | RECONSTRUCTION | 1 | ORIGINAL LIFECYCLE |
| 2 | 100 | RECONSTRUCTION | 2 | CURRENT LIFECYCLE |
| 3 | 100 | INSPECTION | 2 | CURRENT LIFECYCLE |
| 4 | 100 | INSPECTION | 2 | CURRENT LIFECYCLE |
| 5 | 100 | INSPECTION | 2 | CURRENT LIFECYCLE |
| 6 | 100 | INSPECTION | 2 | CURRENT LIFECYCLE |
+----------+---------+----------------+------------------+--------------------+
| 7 | 200 | INSPECTION | 0 | ORIGINAL LIFECYCLE |
| 8 | 200 | RECONSTRUCTION | 1 | PAST LIFECYCLE |
| 9 | 200 | INSPECTION | 1 | PAST LIFECYCLE |
| 10 | 200 | INSPECTION | 1 | PAST LIFECYCLE |
| 11 | 200 | RECONSTRUCTION | 2 | PAST LIFECYCLE |
| 12 | 200 | INSPECTION | 2 | PAST LIFECYCLE |
| 13 | 200 | INSPECTION | 2 | PAST LIFECYCLE |
| 14 | 200 | INSPECTION | 2 | PAST LIFECYCLE |
| 15 | 200 | RECONSTRUCTION | 3 | CURRENT LIFECYCLE |
+----------+---------+----------------+------------------+--------------------+
| 16 | 300 | RECONSTRUCTION | 1 | CURRENT LIFECYCLE |
+----------+---------+----------------+------------------+--------------------+
| 17 | 400 | INSPECTION | 0 | CURRENT LIFECYCLE |
+----------+---------+----------------+------------------+--------------------+
| 18 | 500 | RECONSTRUCTION | 1 | ORIGINAL LIFECYCLE |
| 19 | 500 | RECONSTRUCTION | 2 | CURRENT LIFECYCLE |
+----------+---------+----------------+------------------+--------------------+
| 20 | 600 | INSPECTION | 0 | CURRENT LIFECYCLE |
| 21 | 600 | INSPECTION | 0 | CURRENT LIFECYCLE |
+----------+---------+----------------+------------------+--------------------+
Is there a way to succinctly categorize the rows into current lifecycle
, original lifecycle
, and past lifecycle
, where applicable?
I can think of some lengthy/cumbersome ways to do it with case
statements and subqueries, but I'm looking for something a bit more elegant than that.
Update:
-
I've updated the question with a few more scenarios (roads 300-600). Credit goes to @markp for thinking of this.
-
@markp also highlighted that
current lifecycle
trumpsoriginal lifecycle
.
Best Answer
You can use two window functions,
min()
andmax()
with the same window, over thepartition by road_id
:You could also use
first_value()
andlast_value()
window functions.Test at dbfiddle.uk