If I have a table structure like this:
ProductCode Date
Foo 4/1/2012
Foo 4/2/2012
Foo 4/3/2012
Foo 4/6/2012
Foo 4/7/2012
Foo 4/8/2012
Foo 4/9/2012
Foo 4/10/2012
Foo 4/15/2012
Foo 4/16/2012
Foo 4/17/2012
Is there a way to query for the date range for a given ProductCode and Date (assuming that ranges MUST be sequential)? In other words, for this table, Foo exists on 3 date ranges: 4/1-4/3; 4/6-4/10; and 4/15-4/17 and I'm looking for the date range given a date.
Please note that Foo doesn't have date's 4/4, 4/5, 4/11, 4/12, 4/13 and 4/14.
Examples:ProductCode=Foo, Date=4/2 would return 4/1-4/3 because the entries are sequential.ProductCode=Foo, Date=4/4 would return nothingProductCode=Foo, Date=4/7 would return 4/6-4/10 because the entries are sequential.ProductCode=Foo, Date=4/12 would return nothing
etc.
A new range starts when there is no row for the previous day. If you are running SQL Server 2012, you can use the lag window function to check if a row introduces a new range. Once you know which rows introduce a new range, you can count the number of head rows to assign a unique number to each range.
Having a range number allows you to find the start and end date with min and max. After that, it's just a question of selecting the row:
; with IsHead as
(
select ProductCode
, Date
, case when lag(Date) over (partition by ProductCode
order by Date) = dateadd(day, -1, Date) then 0
else 1 end as IsHead
from YourTable
)
, RangeNumber as
(
select ProductCode
, Date
, sum(IsHead) over (partition by ProductCode order by Date)
as RangeNr
from IsHead
)
, Ranges as
(
select *
, min(Date) over (partition by RangeNr) as RangeStart
, max(Date) over (partition by RangeNr) as RangeEnd
from RangeNumber
)
select *
from Ranges
where ProductCode = 'Bar'
and Date = '4/2/2012'
Example at SQL Fiddle.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With