Aggregate Overlapping Segments to Measure Effective Length

前端 未结 6 788
我寻月下人不归
我寻月下人不归 2021-02-07 02:08

I have a road_events table:

create table road_events (
    event_id number(4,0),
    road_id number(4,0),
    year number(4,0),
    from_meas number         


        
6条回答
  •  挽巷
    挽巷 (楼主)
    2021-02-07 02:22

    This finds expands the table to produce a row for each mile of each road, and simply takes the MAX year. We can just then COUNT the number of rows to produce the event_length.

    It produces the table exactly as you specified above.

    Note: I ran this query against SQL Server. You could use LEAST instead of SELECT MIN(event_length) FROM (VALUES...) in Oracle I think.

    WITH NumberRange(result) AS 
    (
        SELECT 0
        UNION ALL
        SELECT result + 1
        FROM   NumberRange 
        WHERE  result < 301 --Max length of any road
    ),
    CurrentRoadEventLength(road_id, [year], event_length) AS
    (
        SELECT road_id, [year], COUNT(*) AS event_length
        FROM   (
                SELECT re.road_id, n.result, MAX(re.[year]) as [year]
                FROM   road_events re INNER JOIN NumberRange n 
                       ON (    re.from_meas <= n.result 
                           AND re.to_meas > n.result
                          )
                GROUP BY re.road_id, n.result
               ) events_per_mile
        GROUP BY road_id, [year]
    )
    SELECT re.event_id, re.road_id, re.[year], re.total_road_length, 
           (SELECT MIN(event_length) FROM (VALUES (re.to_meas - re.from_meas), (cre.event_length)) AS EventLengths(event_length))
    FROM   road_events re INNER JOIN CurrentRoadEventLength cre
           ON (    re.road_id = cre.road_id
               AND re.[year] = cre.[year]
              )
    ORDER BY re.event_id, re.road_id
    OPTION (MAXRECURSION 301) --Max length of any road
    

提交回复
热议问题