sql server - Count Consecutive Days where value greater than 0 -


using sql server 2012, trying create query provides me with, say, top 10 longest wet (or dry) periods climate database.

my temp table provides following data output:

select monthid [id], date, rain_today  #raindays order monthid asc, date asc 

output:

id  date            rain_today ------------------------------- 1   24 dec 2014     2.4 1   25 dec 2014     0 1   26 dec 2014     8.7 1   27 dec 2014     1.8 1   28 dec 2014     0.3 1   29 dec 2014     0 1   30 dec 2014     0 1   31 dec 2014     0.3 2   01 jan 2015     0.3 2   02 jan 2015     0.3 2   03 jan 2015     18.3 2   04 jan 2015     0.3 

etc. etc.

i return ranked table count period rain_today > 0, (or rain_today = 0) i.e:

rank start_date   end_date    wet period ---------------------------------------- 1    31 dec 2014  04 jan 2015 5 2    26 dec 2014  28 dec 2014 3 

...

the closest have got reviewing other similar queries following (this dry days):

 select       #raindays.monthid id,      min(#raindays.date) [firstdryday],      max(#raindays.date) [latestdryday],      count(*) countdays        (select            monthid,            coalesce(max(case                            when rain_today > '0'                               #raindays.date end), '19000101') latestdry                #raindays      group           monthid) g join      #raindays on #raindays.monthid = g.monthid               , #raindays.date > g.latestdry group      #raindays.monthid order      countdays desc 

output:

id  firstdryday     latestdryday    countdays ----------------------------------------------- 23  21 oct 2016     31 oct 2016     11 21  23 aug 2016     31 aug 2016     9 **15    23 feb 2016     29 feb 2016     7** 10  25 sep 2015     30 sep 2015     6 8   28 jul 2015     31 jul 2015     4 24  28 nov 2016     30 nov 2016     3 29  29 apr 2017     30 apr 2017     2 30  30 may 2017     31 may 2017     2 31  29 jun 2017     30 jun 2017     2 20  30 jul 2016     31 jul 2016     2 7   29 jun 2015     30 jun 2015     2 5   30 apr 2015     30 apr 2015     1 11  31 oct 2015     31 oct 2015     1 17  30 apr 2016     30 apr 2016     1 22  30 sep 2016     30 sep 2016     1 

as can see, don't want group id want able span on different months , i'm missing other periods occur earlier in month. actual count working fine correctly seems, checking above highlighted period:

id  date    rain_today 15  22 feb 2016     3.9 15  23 feb 2016     0 15  24 feb 2016     0 15  25 feb 2016     0 15  26 feb 2016     0 15  27 feb 2016     0 15  28 feb 2016     0 15  29 feb 2016     0 16  01 mar 2016     3 

thanks in advance help!

is want???

if object_id('tempdb..#testdata', 'u') not null  drop table #testdata;  create table #testdata (     id int not null ,     [date] date not null,     rain_today decimal(9,2) not null      );  insert #testdata (id, date, rain_today) values      (1, '24 dec 2014', 2.4),     (1, '25 dec 2014', 0),     (1, '26 dec 2014', 8.7),     (1, '27 dec 2014', 1.8),     (1, '28 dec 2014', 0.3),     (1, '29 dec 2014', 0),     (1, '30 dec 2014', 0),     (1, '31 dec 2014', 0.3),     (2, '01 jan 2015', 0.3),     (2, '02 jan 2015', 0.3),     (2, '03 jan 2015', 18.3),     (2, '04 jan 2015', 0.3);  --======================================       cte_addrankgroup (         select              td.id,             td.date,             td.rain_today,             hr.hasrain,             rankgroup = dense_rank() on (partition td.id order td.date) -                 dense_rank() on (partition td.id, hr.hasrain order td.date)                      #testdata td             cross apply ( values (iif(td.rain_today = 0, 0, 1)) ) hr (hasrain)         ) select      arg.id,     begdate = min(arg.date),     enddate = max(arg.date),     wetperiod = iif(arg.hasrain = 1, 'wet', 'dry'),     consecutivedays = count(1)      cte_addrankgroup arg group      arg.id,     arg.hasrain,     arg.rankgroup order      arg.id,     min(arg.date); 

results...

id          begdate     enddate     wetperiod consecutivedays ----------- ----------  ----------  --------- --------------- 1           2014-12-24  2014-12-24  wet       1 1           2014-12-25  2014-12-25  dry       1 1           2014-12-26  2014-12-28  wet       3 1           2014-12-29  2014-12-30  dry       2 1           2014-12-31  2014-12-31  wet       1 2           2015-01-01  2015-01-04  wet       4 

edit: code version using case expression in place of iif...

--======================================       cte_addrankgroup (         select              td.id,             td.date,             td.rain_today,             hr.hasrain,             rankgroup = dense_rank() on (partition td.id order td.date) -                 dense_rank() on (partition td.id, hr.hasrain order td.date)                      #testdata td             cross apply ( values (case when td.rain_today = 0 0 else 1 end) ) hr (hasrain)         ) select top 10     arg.id,     begdate = min(arg.date),     enddate = max(arg.date),     wetperiod = case when arg.hasrain = 1 'wet' else 'dry' end,     consecutivedays = count(1)      cte_addrankgroup arg      arg.hasrain = '0' -- top 10 dry     --arg.hasrain = '1' -- top 10 wet group      arg.id,     arg.hasrain,     arg.rankgroup order      consecutivedays desc, min(arg.date); 

modified original script produce top 10 each period type ultimate aim (output full dataset):

id  begdate enddate wetperiod   consecutivedays 31  10 jun 2017     26 jun 2017     dry 17 4   02 mar 2015     14 mar 2015     dry 13 5   12 apr 2015     24 apr 2015     dry 13 20  15 jul 2016     26 jul 2016     dry 12 29  01 apr 2017     11 apr 2017     dry 11 26  17 jan 2017     27 jan 2017     dry 11 23  21 oct 2016     31 oct 2016     dry 11 25  01 dec 2016     09 dec 2016     dry 9 21  10 aug 2016     18 aug 2016     dry 9 21  23 aug 2016     31 aug 2016     dry 9 

Comments

Popular posts from this blog

node.js - Node js - Trying to send POST request, but it is not loading javascript content -

javascript - Replicate keyboard event with html button -

javascript - Web audio api 5.1 surround example not working in firefox -