Я думаю, что это должно работать (я предполагаю, что транзакции имеют компонент даты, и что пользователь может иметь несколько транзакций в один день):
;with DailyTransactions as (
select UserID,DATEADD(day,DATEDIFF(day,0,DateAdded),0) as DateOnly,SUM(Amount) as Amount
from Transactions group by UserID,DATEADD(day,DATEDIFF(day,0,DateAdded),0)
), Numbers as (
select ROW_NUMBER() OVER (ORDER BY object_id) as n from sys.objects
), DayRange as (
select n from Numbers where n between 1 and 29
)
select
dt.UserID,dt.DateOnly as StartDate,MAX(ot.DateOnly) as EndDate, dt.Amount + COALESCE(SUM(ot.Amount),0) as TotalSpend
from
DailyTransactions dt
cross join
DayRange dr
left join
DailyTransactions ot
on
dt.UserID = ot.UserID and
DATEADD(day,dr.n,dt.DateOnly) = ot.DateOnly
group by dt.UserID,dt.DateOnly,dt.Amount
having dt.Amount + COALESCE(SUM(ot.Amount),0) >= 100.00
Хорошо, я использую 3 общих табличных выражения. Первый (DailyTransactions) - это уменьшение таблицы транзакций до одной транзакции на пользователя в день (в этом нет необходимости, если DateAdded является только датой, а у каждого пользователя одна транзакция в день). Второй и третий (Numbers и DayRange) немного обмануты - я хотел, чтобы номера 1-29 были доступны для меня (для использования в DATEADD). Существует множество способов создания постоянной или (как в данном случае) временной таблицы чисел. Я выбрал один, а затем в DayRange отфильтровал его до нужных мне чисел.
Теперь, когда у нас есть те, которые нам доступны, мы пишем основной запрос. Мы запрашиваем строки из таблицы DailyTransactions, но мы хотим найти более поздние строки в той же таблице, которые находятся в пределах 30 дней. Именно этим и занимается левое присоединение к DailyTransactions. Он находит те более поздние строки, которых может быть 0, 1 или больше. Если их больше одного, мы хотим сложить все эти значения вместе, поэтому на этом этапе нам нужно еще немного сгруппировать. Наконец, мы можем написать наш пункт «Имея», чтобы отфильтровать только те результаты, в которых сумма за определенный день (dt.Amount
) + сумма сумм за более поздние дни (SUM(ot.Amount)
) соответствует установленным вами критериям. *
Я основал это на таблице, определенной таким образом:
create table Transactions (
UserID int not null,
DateAdded datetime not null,
Amount decimal (38,2)
)