【发布时间】:2019-02-04 11:32:00
【问题描述】:
我有一个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 Problem)。另一方面,它可能会提供对问题本质的洞察,所以这里是这样的:
- 为每条道路选择最近的事件。我们将调用最近的事件:
event A。 - 如果
event A是>= total_road_length,那么这就是我所需要的。算法到此结束。 - 否则,获取与
event A不具有相同范围的下一个按时间顺序排列的事件 (event B)。 - 如果
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
【问题讨论】:
-
如果一个事件来自 2010 年 10-100 年和另一个 20-40 年 2020 年,三行 10-20/2010、20-40/2020、40-100/2010,应该返回什么?
-
@dnoeth 不错。我没有想到这一点。
Option 1 (dnoeth's option):返回 3 行就可以了;这是最明确的选择。Option 2:但是,事后看来,我认为没有必要将from_meas和to_meas作为查询的一部分返回。但是有必要知道返回的事件的长度。因此,我们可以只返回一个event_length列,它是10-20/2010和40-100/2010的聚合。当然,20-40/2020是一行。 -
我认为这可以通过分析功能和窗口化来完成。你有很多标准。棘手的部分将是处理重叠。
标签: sql oracle select oracle12c asset-management