Reputation: 157
I am using SQL Server 2012. I have a very large database containing over 40 million records for GPS tracks for mail delivery. I want to be able to figure out how long a letter carrier has been stopped for. So, when the carrier's distance is registered at 0, and every consecutive 0 following, I would like to know the cumulative time spent stopped. I would also like the summing to stop when anything higher than 0 is registered and to start again when a 0 is registered. This is what I have got so far:
SELECT
CASE
WHEN Distance = 0 THEN SUM(Time_s) OVER (ORDER BY [ID] ROWS UNBOUNDED PRECEDING)
WHEN Distance <0 THEN NULL
END as StopTime
FROM data
ORDER BY ID
This is the result:
ID Distance Time_s StopTime
1 6 899 NULL
2 0 789 1688
3 16 740 NULL
4 0 70 2498
5 0 50 2548
6 0 585 3133
7 0 10 3143
8 5 329 NULL
9 6 394 NULL
10 0 570 4436
I am clearly not telling the query to start the counting over again every time the consecutive zero's are interrupted by anything greater than zero. This is the result I want:
ID Distance Time_s StopTime
1 6 899 NULL
2 0 789 789
3 16 740 NULL
4 0 70 70
5 0 50 130
6 0 585 715
7 0 10 725
8 5 329 NULL
9 6 394 NULL
10 0 570 570
Upvotes: 3
Views: 3228
Reputation: 1269773
You can define a group as the cumulative count of the non-zero values before any given value. Then you can use that group for the cumulative sum.
select d.id, d.distance, d.time_s,
(case when d.distance = 0
then sum(case when d.distance = 0 then d.time_s end) over (partition by grp order by id)
end) as StopTime
from (select d.*,
sum(case when distance = 0 then 0 else 1 end) over (order by id) as grp
from data d
) d;
Upvotes: 2