Skip to content
Advertisement

Using SQL to group consecutive items that share a common status (dummy data included)

Given a table that has sometimes repeated statuses within a group (in this case “vehicles”), I want to consolidate those statuses into a single row and aggregate status_seconds. The data looks like this (I’ll include some TSQL below to select dummy data into a temp table to make it easy to work with this example)

raw data

I want to, for example, consolidate the first three rows of this table for vehicle T101 into a single row with status_seconds = 1+1+2 (4 seconds). For the dummy data, these are the vehicles with consecutive status rows that need to be consolidated.

data to consolidate

Note that in rows 5-7, the travelling status for T101 is broken up by a T102 status.

This seems like a problem for a recursive CTE to me, but I’m finding it difficult to solve.

So far, I’ve been able to identify the anchor nodes for the above. I.e. for each vehicle, I can identify the last occurrence of a status for a vehicle. Here’s the dummy data and a CTE that identifies Anchor nodes.

RESULT anchor nodes

However, I’m struggling to make the recursive CTE work:

–Select * From cte_AnchorNodes a order by a.vehicle_name, a.status_end_time

Advertisement

Answer

This is a typical gaps-and-islands problem, where you want to group together “adjacent” rows that share the same vehicle and status (the islands).

You don’t need a recursive query for this: window functions can get this done. Here, the simplest approach probably is to use the difference between row numbers to identify the groups.

You can run the subquery separately and look how the row numbers change to understand more.

For your sample data, the query returns:

vehicle_name | vehicle_status | min_status_end_time     | max_status_end_time     | sum_status_seconds
:----------- | :------------- | :---------------------- | :---------------------- | -----------------:
T101         | STOPPED        | 2020-12-04 09:43:18.000 | 2020-12-04 09:43:20.000 |                  4
T101         | TURNING        | 2020-12-04 09:43:22.000 | 2020-12-04 09:43:22.000 |                  1
T101         | TRAVELLING     | 2020-12-04 09:43:23.000 | 2020-12-04 09:43:33.000 |                 11
T101         | TURNING        | 2020-12-04 09:43:34.000 | 2020-12-04 09:43:34.000 |                  1
T101         | TRAVELLING     | 2020-12-04 09:43:35.000 | 2020-12-04 09:43:35.000 |                  1
T101         | STOPPED        | 2020-12-04 09:43:35.000 | 2020-12-04 09:43:35.000 |                  3
T102         | STOPPED        | 2020-12-04 09:43:23.000 | 2020-12-04 09:43:23.000 |                 10
T102         | STOPPPED       | 2020-12-04 09:43:33.000 | 2020-12-04 09:43:35.000 |                 10
T102         | PARKED         | 2020-12-04 09:43:35.000 | 2020-12-04 09:43:35.000 |                 10
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement