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
Post a Comment