- Aug 1, 2003
- 9,057
- 0
- 76
I have a table which lists the minutes for a day and the action being taken at that time.
For reasons I'm not going to get into, it is in the general format
What I would like to do is count the number of times each Action occurs in sequential order to find how long it took to do.
Each action can occur more than once, so it's not a simple matter of maxtime - mintime.
e.g.
The closest I've managed to get so far isn't pretty. It uses common table expressions and a quirky update...
Stripped to the basics code:
it's fast, but it's behaving... quirkily.
I do realize it's working from the bottom up, but it's curiously inconsistent. It'll be correct for large stretches of time and then go crazy for one or two actions then be correct again. The table itself is populated correctly and doesn't contain any nulls. There are no duplicate times and each time has only one action associated with it.
It's easily solvable with a loop, but execution time is unacceptable even with small datasets.
Is there a good way to go about doing this?
SQL Server 2008
For reasons I'm not going to get into, it is in the general format
Code:
Time Action
---- ------
00:00 Action a
00:01 Action b
00:02 Action c
...
23:57 Action x
23:58 Action y
23:59 Action z
What I would like to do is count the number of times each Action occurs in sequential order to find how long it took to do.
Each action can occur more than once, so it's not a simple matter of maxtime - mintime.
e.g.
Code:
Time Action Minutes
---- ------ --------
00:00 Action A 4
00:01 Action A 3
00:02 Action A 2
00:03 Action A 1
00:04 Action B 4
00:05 Action B 3
00:06 Action B 2
00:07 Action B 1
00:08 Action A 4
00:09 Action A 3
00:10 Action A 2
00:11 Action A 1
The closest I've managed to get so far isn't pretty. It uses common table expressions and a quirky update...
Stripped to the basics code:
Code:
DECLARE @NumDupedA int = 0
;WITH cte as(
SELECT TOP 1500 ta.ActionA,
ta2.ActionA as ActionA2,
ta.MinutesA
FROM #TimeAction ta
LEFT JOIN #TimeAction ta2 on ta2.Time = DATEADD(minute, 1, ta.Time)
ORDER BY ta.Time DESC
)
UPDATE cte
SET @NumDupedA = MinutesA = (CASE WHEN ActionA = ActionA2 THEN @NumDupedA + 1 ELSE 1 END)
it's fast, but it's behaving... quirkily.
Code:
Time Action Minutes
0:00 A 26
0:01 A 25
0:24 A 2
0:25 A 1
0:26 Z 6
0:27 Z 5
...
0:30 Z 2
0:31 Z 1
0:32 B 36
0:33 B 35
1:06 B 2
1:07 B 1
1:08 C 36
1:09 C 35
1:32 C 12
1:33 C 11
1:34 C 10
1:35 C 9 <-- does great up to here
1:36 C 1 <
1:37 D 16
1:38 D 14 <-- ?
1:39 D 12 |
1:40 D 10 |
1:41 D 8 v
1:42 D 6
1:43 D 4
1:44 D 2
1:45 D 9 <-- ?
...
I do realize it's working from the bottom up, but it's curiously inconsistent. It'll be correct for large stretches of time and then go crazy for one or two actions then be correct again. The table itself is populated correctly and doesn't contain any nulls. There are no duplicate times and each time has only one action associated with it.
It's easily solvable with a loop, but execution time is unacceptable even with small datasets.
Is there a good way to go about doing this?
SQL Server 2008
Last edited: