SQL Query根据日期对记录进行分区

时间:2015-11-20 12:16:27

标签: sql sql-server-2008

我有一个要求,我想根据两个表中的数据排除某些记录。要求是产品包含在certaiun期间,然后在两个不同的时期被排除。我必须拿出决赛桌,告诉我们产品实际包含在哪个范围内。 我尝试过多次查询,但没有运气。

Declare @DtlInc table
(prod varchar(32),
eff_dt date,
end_dt date
)

Declare @DtlExclu table
(prod varchar(32),
eff_dt date,
end_dt date
)

Insert into @pgDtlInc values ('A','01/01/2013','12/31/8888')
Insert into @pgDtlExclu values ('A','01/01/2012','12/31/2015')
Insert into @pgDtlExclu values ('A','01/01/2018','12/31/2020')


Final Data(Included) :
A   01/01/2016 12/31/2017
A   01/01/2021 12/31/8888

TIA

阿米特

1 个答案:

答案 0 :(得分:0)

这可能是一个具有挑战性的问题。这是一种方法,它将每个日期分成一个单独的行,同时指示日期是否意味着包括"包括"或"排除"。

然后,取这个标志的累积总和。累积总和现在将日期分成组,这些组由零值分隔。通过此组(和prod)进行汇总时,您可以获得包含的时段:

with pd as (
      select prod, eff_dt as dt, 1 as inc
      from @DtlInc
      union all
      select prod, end_dt, -1 as inc
      from @DtlInc
      union all
      select prod, eff_dt, -1 as inc
      from @DtlExclu
      union all
      select prod, end_dt, 1 as inc
      from @DtlExclu
     ),
     pdcume as (
      select pd.*, pdc.cumeinc
      from pd outer apply
           (select sum(inc) as cumeinc
            from pd2
            where pd2.prod = pd.prod and
                  pd2.dt <= pd.dt
           ) pdc
     ),
     pdg (
      select pd.*, pdg.grp
      from pd outer apply
           (select count(*) as grp
            from pdcume pdcume2
            where pdcume2.prod = pdcum.prod and pdcume2.dt < pd.dt and
                  pdcume2.cumeinc = 0
           ) pdg
     )
select prod, min(dt) as startdate, max(dt) as enddate
from pdg
group by prod;

注意:当日期不同时,此逻辑应该有效,尽管可能存在一个错误,具体取决于结束日期是包含还是排除。当重复日期时,这个问题更加棘手。使用SQL Server 2012+中的增强功能来表示更容易一些,因此这可能是升级到更新版本数据库的一个很好的理由。