Search code examples
sql-server-2008-r2lag

SQL Server 2008 (No LAG function) - Group Min/Max date when Value changes


I have an existing @table

ID  Date    Val
1   2014-10-01  1
2   2014-10-02  1
3   2014-10-03  2
4   2014-10-04  2
5   2014-10-05  2
6   2014-10-06  1
7   2014-10-07  1
8   2014-10-08  1
9   2014-10-09  1

The Date sequence is of importance. I need to see the first and last date for each Val sequence:

How do I get SQL to return the min/max dates per sequence? I need to show : i.e.

1   2014-10-01  2014-10-02
2   2014-10-03  2014-10-05
1   2014-10-06  2014-10-09

I got this working with the help of other developers with 2012's LAG function, but I need to use 2008 please

Failed attempt:

  select t.Val,MIN(t.date),MAX(tnext.date)
from @T t join
     @T tnext
     on t.id = tnext.id - 1 and
      t.Val <> tnext.val
      group by 
      t.val

Setup:

declare @T table(ID int,[Date] date,Val int)
Insert Into @T(ID,[Date],Val)
 values
(1,'2014/10/01',    1),
(2,'2014/10/02',    1),
(3,'2014/10/03',    2),
(4,'2014/10/04',    2),
(5,'2014/10/05',    2),
(6,'2014/10/06',    1),
(7,'2014/10/07',    1),
(8,'2014/10/08',    1),
(9,'2014/10/09',    1)

Solution

  • I believe this query should work:

    select 
        val, 
        start_date = min(date), 
        end_date   = max(date) 
    from 
        (
        select 
           val, 
           date, 
           grp = row_number() over (partition by val order by date) 
               - row_number() over (order by date) 
        from 
           @t 
        ) x 
    group by 
        grp, val
    order by 
        min(date)
    

    The query above assumes that the dates are strictly sequential.

    Sample SQL Fiddle