У меня есть таблица road_events
:
create table road_events (
event_id number(4,0),
road_id number(4,0),
year number(4,0),
from_meas number(10,2),
to_meas number(10,2),
total_road_length number(10,2)
);
insert into road_events (event_id, road_id, year, from_meas, to_meas, total_road_length) values (1,1,2020,25,50,100);
insert into road_events (event_id, road_id, year, from_meas, to_meas, total_road_length) values (2,1,2000,25,50,100);
insert into road_events (event_id, road_id, year, from_meas, to_meas, total_road_length) values (3,1,1980,0,25,100);
insert into road_events (event_id, road_id, year, from_meas, to_meas, total_road_length) values (4,1,1960,75,100,100);
insert into road_events (event_id, road_id, year, from_meas, to_meas, total_road_length) values (5,1,1940,1,100,100);
insert into road_events (event_id, road_id, year, from_meas, to_meas, total_road_length) values (6,2,2000,10,30,100);
insert into road_events (event_id, road_id, year, from_meas, to_meas, total_road_length) values (7,2,1975,30,60,100);
insert into road_events (event_id, road_id, year, from_meas, to_meas, total_road_length) values (8,2,1950,50,90,100);
insert into road_events (event_id, road_id, year, from_meas, to_meas, total_road_length) values (9,3,2050,40,90,100);
insert into road_events (event_id, road_id, year, from_meas, to_meas, total_road_length) values (10,4,2040,0,200,200);
insert into road_events (event_id, road_id, year, from_meas, to_meas, total_road_length) values (11,4,2013,0,199,200);
insert into road_events (event_id, road_id, year, from_meas, to_meas, total_road_length) values (12,4,2001,0,200,200);
insert into road_events (event_id, road_id, year, from_meas, to_meas, total_road_length) values (13,5,1985,50,70,300);
insert into road_events (event_id, road_id, year, from_meas, to_meas, total_road_length) values (14,5,1985,10,50,300);
insert into road_events (event_id, road_id, year, from_meas, to_meas, total_road_length) values (15,5,1965,1,301,300);
commit;
select * from road_events;
EVENT_ID ROAD_ID YEAR FROM_MEAS TO_MEAS TOTAL_ROAD_LENGTH
---------- ---------- ---------- ---------- ---------- -----------------
1 1 2020 25 50 100
2 1 2000 25 50 100
3 1 1980 0 25 100
4 1 1960 75 100 100
5 1 1940 1 100 100
6 2 2000 10 30 100
7 2 1975 30 60 100
8 2 1950 50 90 100
9 3 2050 40 90 100
10 4 2040 0 200 200
11 4 2013 0 199 200
12 4 2001 0 200 200
13 5 1985 50 70 300
14 5 1985 10 50 300
15 5 1965 1 301 300
Я хочу выбрать события, которые представляют самую последнюю работу на каждой дороге.
Это сложная операция, потому что события часто относятся только к части дороги. Это означает, что я не могу просто выбрать последнее событие на дорогу; Мне нужно только выбрать самый последний пробег событий, который не перекрывается.
Возможная логика (по порядку):
Я не хочу догадываться, как эта проблема может быть решена, потому что это может привести к большему большему, чем это помогает (вроде как проблема XY). С другой стороны, это могло бы дать представление о природе проблемы, поэтому здесь говорится:
- Выберите последнее событие для каждой дороги. Мы будем называть самое последнее событие:
event A
- Если
event A
>= total_road_length
, тогда все, что мне нужно. Алгоритм заканчивается здесь. - Иначе, получите следующее хронологическое событие (
event B
), которое не имеет таких же экстентов, какevent A
- Если экстенты
event B
перекрывают экстентыevent A
, то только получите частьevent B
которые не пересекаются. - Повторите шаги 3 и 4, пока общая длина события не будет
= total_road_length
. Или остановитесь, когда на этой дороге больше нет событий.
Вопрос:
Я знаю, что это высокий порядок, но для чего это нужно?
Это классическая линейная проблема ссылок. Было бы очень полезно, если бы я мог выполнять операции линейной ссылки как часть запросов.
Результатом будет:
EVENT_ID ROAD_ID YEAR TOTAL_ROAD_LENGTH EVENT_LENGTH
---------- ---------- ---------- ----------------- ------------
1 1 2020 100 25
3 1 1980 100 25
4 1 1960 100 25
5 1 1940 100 25
6 2 2000 100 20
7 2 1975 100 30
8 2 1950 100 30
9 3 2050 100 50
10 4 2040 200 200
13 5 1985 300 20
14 5 1985 300 40
15 5 1965 300 240
Связанный вопрос: выберите, где диапазон номеров не перекрывается