I have read up on and attempted using the standard method of gaps and island detection in a series with no success because I need to be able to ignore any gaps less than 30 minutes. I can not use a cursor due to performance issues.
Everytime there is a gap of at least 30 min, I need a new row with the start and end. If there are no gaps of at least 30, result would be one row with the min and max of the timestamps. If there is 1 gap of at least 30, there would be 2 rows - from the start of the series to the gap and from the gap to the end. If there are more gaps, we get rows for each interval between the gaps, etc.
Input:
timestamp
2015-07-15 15:01:21
2015-07-15 15:17:44
2015-07-15 15:17:53
2015-07-15 15:18:34
2015-07-15 15:21:41
2015-07-15 15:58:12
2015-07-15 15:59:12
2015-07-15 16:05:12
2015-07-15 17:02:12
Desired output :
from | to
2015-07-15 15:01:21 | 2015-07-15 15:21:41
2015-07-15 15:58:12 | 2015-07-15 16:05:12
2015-07-15 17:02:12 | 2015-07-15 17:02:12
Easy solution using common table expression. Compare with cursor performance if you have at least 1000 rows.
Test
Result
If a post answers your question, please Mark it as answer
Remember that
datediff()
just counts interval boundaries so you need to take some care with the time difference. I'm using 1800 seconds here.If you had a later edition of SQL Server you could use
lead()/lag()
to look for the gaps. But instead of an inner join the cross apply will hopefully be significantly faster.I think your title "find gaps over 30 minutes" as well as a comment to "ignore gaps less than 30 minutes" has misled some posters who thought that you were only seeking to find the rows that bounded a gap of 30 minutes. This is the only one that addresses the problem according to your desired output. (Test here.)
Instead of using analytic
sum() over (order by...)
it's a simple matter of replacing it with a scalar subquery.An approach like the one below would seem to fit the bill assuming the performance is okay. I used the
sys.all_tables
catalog view to simulate a log table like the one in your example. You can vary the first argument todatediff
to get different results.Don't forget the statement before this one in the batch must be terminated with a
;
or this statement must start with one.