The grp
column should be represent a block partitioned by GroupId, RouteId
and ordered LengthStart
where as you travel through the blocks if the locationId remains the same the grp
is the same. A break in the sequence creates a new grp
+---------+----------+--------------+------------+-------------+------+
| GROUPID | ROUTEID | LENGTHSTART | LENGTHEND | LOCATIONID | GRP |
+---------+----------+--------------+------------+-------------+------+
| 1 | A | 0 | 1 | 1 | 1 |
| 1 | A | 1 | 2 | 1 | 1 |
| 1 | A | 2 | 3 | 2 | 2 |
| 1 | A | 3 | 4 | 1 | 3 |
| 2 | A | 2 | 3 | 2 | 4 |
| 1 | B | 2 | 3 | 2 | 5 |
| 1 | A | 4 | 5 | 1 | 3 |
+---------+----------+--------------+------------+-------------+------+
My search on this problem led me to this solution: DENSE_RANK according to particular order
My attempt at making the grp
calculation:
SELECT *, ROW_NUMBER() OVER (ORDER BY GroupId, RouteId, LengthStart) - ROW_NUMBER() OVER (PARTITION BY GroupId, RouteId, LocationId ORDER BY GroupId, RouteId, LengthStart) AS grp
FROM mytable
I tried to adopt that solution such that I could have more levels of partitioning and it works in really basic use-cases (like the one showcased above but in complicated scenarios its failing).
I don't really understand completely why two row_number() are subtracting and how it works out but it worked really well in the simple example.
I tried other approaches uses LAG
but just fail to understand how to take the logic and apply it.
Here is a fiddle with the more complicated scenerio:
https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=3704dfe8583b0dd020b189184d149cb7
You can see one of the many mistakes I've been seeing highlighted here: