For a report, i need to track movement of persons from one place to another within a given time range, based on their activities
Activities
Name | TimeStamp | Activity |
---|---|---|
Peter | 10-JAN-23 05:23:06 | Gym |
Peter | 10-JAN-23 07:01:45 | Home |
Peter | 10-JAN-23 08:09:26 | Restaurant |
Peter | 10-JAN-23 09:19:32 | Office |
Peter | 10-JAN-23 16:43:02 | Golf |
John | 10-JAN-23 07:30:26 | Home |
John | 10-JAN-23 08:30:43 | Gym |
John | 10-JAN-23 10:02:06 | Theater |
John | 10-JAN-23 12:00:32 | Soccer |
John | 10-JAN-23 20:23:02 | Bar |
From the above table, let's say we need to track movement of people from 8AM to 8PM (08:00 to 20:00) the result would be as below.
Name | From | To |
---|---|---|
Peter | Home | Restaurant |
Peter | Restaurant | Office |
Peter | Office | Golf |
John | Home | Gym |
John | Gym | Theater |
John | Theater | Soccer |
Using BETWEEN in WHERE CLAUSE the activity between the given range can be fetched. But I am unable to get the first 'FROM' place of each person as it falls outside the time range. I have tried with group by and window functions, but still unable to get the desired result. Can someone please help on this ?
Name | From | To |
---|---|---|
Peter | ????? | Restaurant |
Peter | Restaurant | Office |
Peter | Office | Golf |
John | ????? | Gym |
John | Gym | Theater |
John | Theater | Soccer |
Use the LAG
analytic function in an inner-query and then filter on the time range in an outer query (if you do it the other way round then you will filter out the value before the start of the range before you can find it using LAG
):
SELECT name,
prev_activity AS "FROM",
activity AS "TO"
FROM (
SELECT a.*,
LAG(activity) OVER (PARTITION BY name ORDER BY timestamp) AS prev_activity
FROM activites a
)
WHERE timestamp BETWEEN TIMESTAMP '2023-01-10 08:00:00'
AND TIMESTAMP '2023-01-10 20:00:00';
Which, for the sample data:
CREATE TABLE activities ( Name, TimeStamp, Activity ) AS
SELECT 'Peter', TIMESTAMP '2023-01-10 05:23:06', 'Gym' FROM DUAL UNION ALL
SELECT 'Peter', TIMESTAMP '2023-01-10 07:01:45', 'Home' FROM DUAL UNION ALL
SELECT 'Peter', TIMESTAMP '2023-01-10 08:09:26', 'Restaurant' FROM DUAL UNION ALL
SELECT 'Peter', TIMESTAMP '2023-01-10 09:19:32', 'Office' FROM DUAL UNION ALL
SELECT 'Peter', TIMESTAMP '2023-01-10 16:43:02', 'Golf' FROM DUAL UNION ALL
SELECT 'John', TIMESTAMP '2023-01-10 07:30:26', 'Home' FROM DUAL UNION ALL
SELECT 'John', TIMESTAMP '2023-01-10 08:30:43', 'Gym' FROM DUAL UNION ALL
SELECT 'John', TIMESTAMP '2023-01-10 10:02:06', 'Theater' FROM DUAL UNION ALL
SELECT 'John', TIMESTAMP '2023-01-10 12:00:32', 'Soccer' FROM DUAL UNION ALL
SELECT 'John', TIMESTAMP '2023-01-10 20:23:02', 'Bar' FROM DUAL;
Outputs:
NAME | FROM | TO |
---|---|---|
John | Home | Gym |
John | Gym | Theater |
John | Theater | Soccer |
Peter | Home | Restaurant |
Peter | Restaurant | Office |
Peter | Office | Golf |