让我们说我有一个查询,其中我计算每天的事件数量:
**Date** **NumberOfEvents**
2017-11-1 7
2017-11-2 11
2017-11-3 3
...
2017-11-8 24
2017-11-9 6
2017-11-10 10
2017-11-11 9
...
2017-11-22 22
2017-11-23 11
2017-11-24 14
2017-11-25 17
...
2017-11-28 16
2017-11-29 21
2017-11-30 6
...
然后让我说我会定义变量@StartingDay ='2017-11-3'
我希望在@StartingDay之后的下一个4周内获得同一工作日+ -1天的最小值的查询,p.ex:
**Period** **DateWithMin** **MinNumberOfEvents**
2017-11-09 To 2017-11-11 2017-11-9 6
2017-11-16 To 2017-11-18 2017-11-17 8
2017-11-23 To 2017-11-25 2017-11-23 11
2017-11-30 To 2017-12-02 2017-11-30 6
我相信我必须在不同时期循环才能寻找分钟,但我无法找到循环的方法。
答案 0 :(得分:2)
您可以使用模数和日期算法来获取时间段和组:
select min(date), max(date), min(NumberOfEvents)
from t
where (datediff(day, @startingday, date) % 7) in (0, 1, 6) and
date > dateadd(day, 1, @startingday) and
date <= dateadd(day, 4 * 7 + 1, @startingday)
group by (datediff(day, @startingday, date) + 1) / 7;
获取最小事件的日期更加麻烦。这是一种方法:
select min(date), max(date), min(NumberOfEvents),
max(case when seqnum = 1 then date end) as date_at_min
from (select t.*, v.grp,
row_number() over (partition by grp order by numberofevents) as seqnum
from t cross apply
(values ((datediff(day, @startingday, date) + 1) / 7)) v(grp)
) t
where (datediff(day, @startingday, date) % 7) in (0, 1, 6) and
date > dateadd(day, 1, @startingday) and
date <= dateadd(day, 4 * 7 + 1, @startingday)
group by grp;
答案 1 :(得分:2)
另一种方法是使用递归CTE生成From
和To
日期,对结果应用Row_Number()
以查找每个分组Min
,并只选择那些结果:
Declare @StartingDay Date = '2017-11-03',
@NumWeeks Int = 4
;With Dates As
(
Select DateFrom = DateAdd(Day, -1, DateAdd(Week, 1, @StartingDay)),
DateTo = DateAdd(Day, 1, DateAdd(Week, 1, @StartingDay))
Union All
Select DateFrom = DateAdd(Week, 1, DateFrom),
DateTo = DateAdd(Week, 1, DateTo)
From Dates
Where DateTo < DateAdd(Day, 1, DateAdd(Week, @NumWeeks, @StartingDay))
), Results As
(
Select PeriodFrom = D.DateFrom,
PeriodTo = D.DateTo,
NumberOfEvents = Y.NumberOfEvents,
RN = Row_Number() Over (Partition By D.DateFrom, D.DateTo
Order By Y.NumberOfEvents),
Date = Y.Date
From YourTable Y
Join Dates D On Y.Date Between D.DateFrom And D.DateTo
)
Select PeriodFrom,
PeriodTo,
DateWithMin = Date,
MinNumberOfEvents = NumberOfEvents
From Results
Where RN = 1