按日期范围分组与另一个字段组合?

时间:2014-03-10 17:00:16

标签: sql sql-server-2008

在SQL Server 2008中,我有以下内容:

Create table #RateHistory (RatePlan char(1), EventDate datetime)

Insert into #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') 

我希望看到这样的输出:

Rateplan MinDate     MaxDate
-------- ----------- -----------
a        2013-10-01  2013-10-08 
b        2013-10-21  2013-12-05 
a        2013-12-08  2013-12-15 

(原来这有点不同,但我相信这个结果集让我更清楚我真正需要的,这是正确的分组)

请注意,RatePlan“a”显示两次,我希望将其单独分组 - 一次用于10/1/2013到10/8/2013数据,一次用于12/8/2013到12 / 15/2013数据。我已经得到了我需要的解决方案:

-- Get initial row numbers
;with Test as (
    Select 
    *
    ,RowNumber = ROW_NUMBER() over (order by EventDate) 
    from #RateHistory            
)
-- Get initial row numbers
, Test2 as (
SelecT 
    Main.RowNumber
    ,Main.EventDate
    ,Main.RatePlan
    ,FollowingRatePlan = Following.RatePlan
    ,NewGroup = 
        case
            when Main.RatePlan <> Following.RatePlan  
                -- if Following RatePlan is null, that means this is the last record
                or (Following.RatePlan is  null ) 
            then Main.EventDate
            else null
        end
from Test Main 
    left join Test following 
        on Following.RowNumber = Main.RowNumber + 1
)      
, Test3 as (
select 
    #RateHistory.RatePlan
    ,#RateHistory.EventDate
    ,MaxDate = min(Test2.NewGroup)
from #RateHistory  
    join Test2 
        on #RateHistory .RatePlan  = Test2.RatePlan
        and #RateHistory .EventDate <= Test2.NewGroup
where Test2.NewGroup is not null    
group by 
    #RateHistory.RatePlan
    ,#RateHistory.EventDate

)
select Rateplan, MinDate = MIN(EventDate) , MaxDate 
from Test3 
group by RatePlan,MaxDate

......但我在想 - 有一种更好,更优雅的方式来做这件事。思考?如果没有人有更好的东西,我会继续把它作为答案......

谢谢!

1 个答案:

答案 0 :(得分:0)

我可以想到使用相关标量子查询的解决方案。你告诉我它是否更优雅。或者表现更好。

select distinct
  rh0.RatePlan,
  (
    select min(EventDate) 
    from RateHistory rh1 
    where rh1.RatePlan = rh0.RatePlan 
    and rh1.EventDate <= rh0.EventDate
    and not exists 
    (
      select * from RateHistory rh2
      where rh2.RatePlan != rh0.RatePlan
      and rh2.EventDate > rh1.EventDate
      and rh2.EventDate < rh0.EventDate
    )
  ) as mindate,
  (
    select max(EventDate) 
    from RateHistory rh1 
    where rh1.RatePlan = rh0.RatePlan 
    and rh1.EventDate >= rh0.EventDate
    and not exists 
    (
      select * from RateHistory rh2
      where rh2.RatePlan != rh0.RatePlan
      and rh2.EventDate < rh1.EventDate
      and rh2.EventDate > rh0.EventDate
    )
  ) as maxdate
from RateHistory rh0
order by mindate

Check out the SQLFiddle。 BTW 2012有一些很酷的功能,可以使您的查询版本更加优雅。