2017-10-09 117 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,對吧? –