Determine Order Streak
-
22-02-2021 - |
Question
For a particular customer, I have data returned by a query that looks like this:
OrderDate OrderCount
2020-01-12 0
2020-01-13 17
2020-01-14 22
2020-01-15 21
2020-01-16 30
2020-01-17 12
2020-01-18 0
2020-01-20 0
2020-01-21 49
2020-01-22 28
2020-01-23 4
These are the number of orders for each business day for that customer. How do I efficiently determine their current "Streak" of orders? For instance, if today was 2020-01-24, the answer would be 3, since they have ordered 3 days without missing a day.
Note that the days may not always be consecutive. There are some non-business days that aren't returned by the query (ie 2020-01-19 in example).
Can anyone tell me how to do this? Thanks in advance!
Solution
As mustaccio pointed out this is a "gaps and islands" problem:
declare @date date = '2020-01-16';
with ct as
(
/* First you must detect the gaps, filtering those rows lesser than the selected date */
select
OrderDate,
case when
datediff(day,
coalesce(lag(OrderDate) over (order by OrderDate), OrderDate),
OrderDate
) <> 1 then 1 else 0 end rst
from
orders
where
OrderDate <= @date
)
, ct2 as
(
/* Then set an island of each group */
select
OrderDate,
sum(rst) over (order by OrderDate) as grp
from
ct
)
/* And finally count the affected rows */
select top 1
count(OrderDate) streak
from
ct2
group by
grp
order by
max(OrderDate) desc;
| streak | | -----: | | 5 |
db<>fiddle here
Licensed under: CC-BY-SA with attribution
Not affiliated with dba.stackexchange