sql - Grouping by date range combined with another field? -


in sql server 2008, have following:

create table #ratehistory (rateplan char(1), eventdate datetime)  insert #ratehistory  (rateplan, eventdate) values  ('a','10/01/2013')   ,('a','10/04/2013')  ,('a','10/06/2013')  ,('a','10/08/2013')  ,('b','10/21/2013')  ,('b','11/05/2013')  ,('b','11/12/2013')  ,('b','12/05/2013')  ,('a','12/08/2013')  ,('a','12/09/2013')  ,('a','12/10/2013')  ,('a','12/15/2013')  

i'd see output this:

rateplan mindate     maxdate -------- ----------- -----------        2013-10-01  2013-10-08  b        2013-10-21  2013-12-05         2013-12-08  2013-12-15  

(originally bit different, believe result set makes clearer need, correct grouping)

note rateplan "a" shows twice, , want grouped separately - once 10/1/2013 10/8/2013 data, , once 12/8/2013 12/15/2013 data. i've got solution need :

-- initial row numbers ;with test (     select      *     ,rownumber = row_number() on (order eventdate)      #ratehistory             ) -- initial row numbers , test2 ( select      main.rownumber     ,main.eventdate     ,main.rateplan     ,followingrateplan = following.rateplan     ,newgroup =          case             when main.rateplan <> following.rateplan                   -- if following rateplan null, means last record                 or (following.rateplan  null )              main.eventdate             else null         end test main      left join test following          on following.rownumber = main.rownumber + 1 )       , test3 ( select      #ratehistory.rateplan     ,#ratehistory.eventdate     ,maxdate = min(test2.newgroup) #ratehistory       join test2          on #ratehistory .rateplan  = test2.rateplan         , #ratehistory .eventdate <= test2.newgroup test2.newgroup not null     group      #ratehistory.rateplan     ,#ratehistory.eventdate  ) select rateplan, mindate = min(eventdate) , maxdate  test3  group rateplan,maxdate 

...but i'm thinking - there's got better, more elegant way of doing this. thoughts? if nobody has better, i'll go ahead , put in answer...

thanks!

i can think of solution using correlated scalar sub-queries. tell me if it's more elegant. or better performing.

select distinct   rh0.rateplan,   (     select min(eventdate)      ratehistory rh1      rh1.rateplan = rh0.rateplan      , rh1.eventdate <= rh0.eventdate     , not exists      (       select * ratehistory rh2       rh2.rateplan != rh0.rateplan       , rh2.eventdate > rh1.eventdate       , rh2.eventdate < rh0.eventdate     )   ) mindate,   (     select max(eventdate)      ratehistory rh1      rh1.rateplan = rh0.rateplan      , rh1.eventdate >= rh0.eventdate     , not exists      (       select * ratehistory rh2       rh2.rateplan != rh0.rateplan       , rh2.eventdate < rh1.eventdate       , rh2.eventdate > rh0.eventdate     )   ) maxdate ratehistory rh0 order mindate 

check out sqlfiddle. btw 2012 has cool features make version of query more elegant.


Comments

Popular posts from this blog

google app engine - 403 Forbidden POST - Flask WTForms -

Android layout hidden on keyboard show -

Parse xml element into list in Python -