I have a table having data like this:
Vehicle | Start | End | Date |
---|---|---|---|
Truck A | A | B | 02/01/2021 01:00:00 |
Truck A | B | C | 02/01/2021 02:00:00 |
Truck A | C | D | 04/01/2021 03:00:00 |
Truck B | C | A | 05/01/2021 01:00:00 |
Truck B | A | B | 06/01/2021 01:00:00 |
Truck C | C | B | 07/01/2021 01:00:00 |
Truck C | B | C | 08/01/2021 01:00:00 |
Truck C | C | B | 09/01/2021 01:00:00 |
Truck C | B | A | 10/01/2021 01:00:00 |
I need to get the starting and ending point of each vehicle based on the date.
For example, Truck A has started from point A to point B on 02/01/2021 01:00:00. Then Truck A has moved from point B to point C on 02/01/2021 02:00:00. Truck A has moved from point C to point D on 04/01/2021 03:00:00.
It has started from point A and ended at point D.
I want to get a result like this:
Vehicle | Start | End | Date |
---|---|---|---|
Truck A | A | D | 04/01/2021 03:00:00 |
CodePudding user response:
Use GROUP BY
and aggregate using KEEP
to get the FIRST
or LAST
date values:
SELECT vehicle,
MIN("START") KEEP (DENSE_RANK FIRST ORDER BY "DATE") AS "START",
MAX("END") KEEP (DENSE_RANK LAST ORDER BY "DATE") AS "END",
MAX("DATE") AS "DATE"
FROM table_name
GROUP BY vehicle
Which, for the sample data:
CREATE TABLE table_name (Vehicle, "START", "END", "DATE") AS
SELECT 'Truck A', 'A', 'B', DATE '2021-01-02' INTERVAL '1' HOUR FROM DUAL UNION ALL
SELECT 'Truck A', 'B', 'C', DATE '2021-01-02' INTERVAL '2' HOUR FROM DUAL UNION ALL
SELECT 'Truck A', 'C', 'D', DATE '2021-01-04' INTERVAL '3' HOUR FROM DUAL UNION ALL
SELECT 'Truck B', 'C', 'A', DATE '2021-01-05' INTERVAL '1' HOUR FROM DUAL UNION ALL
SELECT 'Truck B', 'A', 'B', DATE '2021-01-06' INTERVAL '1' HOUR FROM DUAL UNION ALL
SELECT 'Truck C', 'C', 'B', DATE '2021-01-07' INTERVAL '1' HOUR FROM DUAL UNION ALL
SELECT 'Truck C', 'B', 'C', DATE '2021-01-08' INTERVAL '1' HOUR FROM DUAL UNION ALL
SELECT 'Truck C', 'C', 'B', DATE '2021-01-09' INTERVAL '1' HOUR FROM DUAL UNION ALL
SELECT 'Truck C', 'B', 'A', DATE '2021-01-10' INTERVAL '1' HOUR FROM DUAL
Outputs:
VEHICLE START END DATE Truck A A D 2021-01-04 03:00:00 Truck B C B 2021-01-06 01:00:00 Truck C C A 2021-01-10 01:00:00
CodePudding user response:
Using the window function FIRST_VALUE to find the first and last for each vehicle
SELECT Vehicle
, FirstStart AS "Start"
, LastEnd AS "End"
, MAX("Date") AS "Date"
FROM
(
SELECT Vehicle, "Start", "End", "Date"
, FIRST_VALUE("Start") OVER (PARTITION BY Vehicle ORDER BY "Date") AS FirstStart
, FIRST_VALUE("End") OVER (PARTITION BY Vehicle ORDER BY "Date" DESC) AS LastEnd
FROM yourtable
) q
GROUP BY Vehicle, FirstStart, LastEnd
ORDER BY Vehicle;