I have table the following data structure in SQL Server:
ID Date Allocation
1, 2012-01-01, 0
2, 2012-01-02, 2
3, 2012-01-03, 0
4, 2012-01-04, 0
5, 2012-01-05, 0
6, 2012-01-06, 5
etc.
What I need to do is get all consecutive day periods where Allocation = 0, and in the following form:
Start Date End Date DayCount
2012-01-01 2012-01-01 1
2012-01-03 2012-01-05 3
etc.
Is it possible to do this in SQL, and if so how?
In this answer, I’ll assume that the “id” field numbers the rows consecutively when sorted by increasing date, like it does in the example data. (Such a column can be created if it does not exist).
This is an example of a technique described here and here.
1) Join the table to itself on adjacent “id” values. This pairs adjacent rows. Select rows where the “allocation” field has changed. Store the result in a temporary table, also keeping a running index.
This gives you a table having “the end of the previous period”, “the start of the next period”, and “the value of ‘allocation’ in the previous period” in each row:
2) We need the start and end of each period in the same row, so we need to combine adjacent rows again. Do this by creating a second temporary table like
boundariesbut having anidxfield 1 greater:Now join on the
idxfield and we get the answer:** Note that this answer gets the “internal” periods correctly but misses the two “edge” periods where allocation = 0 at the beginning and allocation = 5 at the end. Those can be pulled in using
UNIONclauses but I wanted to present the core idea without that complication.