2017-10-09 154 views
1

比方说,我有一个查询中,我算每天的事件数:T-SQL选择最小值

**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'

我想获得与同一工作日+ -1天的最低值查询后@StartingDay,p.ex的4周内:

**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 

我相信我会到c通过不同的时期寻找最小的,但我找不到一个循环的方式。

+2

我没跟随你的预期结果......为什么'2017-11-09'到'2017-11-11'是第一个结果,当@ @ StartingDay'是'2017-11-03' ?当有关系时你选择什么?最早的日期? – Siyual

+0

1.下周同一天(2017-11-10)+ - 1天 2.在这种特殊情况下,没关系,可以是任何 –

回答

3

另一种方式做,这是产生FromTo日期与递归CTE,应用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 
3

可以使用模和日期计算得到的时间段和组:

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; 
+0

我相信第二部分有问题码。我在date_at_min中得到了一些空结果。您正在寻找每周的最小值(seqnum = 1)。但是,如果一周的最小时间超出3天时间,则返回空值。它应该在3天内搜索最小seqnum,对吧? –