您好我有以下问题,我正在尝试找出解决问题的最佳方法。
我有一张名为[Kpi]的表格,数据如下: -
[ContractId] [KpiId] [NotificationIntervalInMonths]
1000 1 3
1000 2 5
我有[合约]表,其中包含: -
[ContractId] [StartDate] [EndDate]
1000 1/Nov/2009 4/Apr/2011
我正在寻找一种方式来显示Kpi何时应在合同的开始日期和结束日期之间通知用户的通知时间表,例如上面的结构将创建以下列/行: -
[ContractId] [KpiId] [NotificationDate]
1000 1 1/Feb/2009
1000 1 1/May/2010
1000 1 1/Aug/2010
1000 1 1/Nov/2010
1000 1 1/Feb/2011
1000 2 1/Apr/2010
1000 2 1/Sep/2010
1000 2 1/Feb/2011
我首先想到我会创建一个每次插入新Kpi时都填充的查找表,这似乎是可行的,看起来似乎是最好的方法。
我的业务逻辑规定不能更改[NotificationIntervalInMonths],但合同的[EndDate]可以更改。这意味着我必须根据新的合同[EndDate]在查找表中添加/删除记录,对我来说这看起来有点乱。
所以这引出了我的问题,是否有一种纯SQL方法可以在不创建查找表的情况下为我提供通知计划?不允许使用游标:P但我希望CTE可以在这里工作。
如果我没有提供足够的信息,请询问。
答案 0 :(得分:1)
创建一个表值函数,该函数接受您的两个日期范围,并返回该范围内每个月的第一个日期。然后在查询中加入该函数。对不起,无法提供更多细节,有人在Skype上骚扰我(哦,是你!)。 :)
答案 1 :(得分:1)
这是答案,如果任何机构可以审查/加强它,那么请让我知道......
declare @startDate datetime, @endDate datetime
set @startDate = '01/Nov/2009'
set @endDate = '04/Apr/2011'
declare @kpi table(kpiid int, interval int)
insert into @kpi
select 1, 3
union select 2, 5
--union select 3, 9
--union select 4, 12
;with mycte(i, d, interval, p, kpiid) as
(
select i = 1, d=@startDate, Interval, 0, kpiid from @kpi
union all
select
i = i + 1,
dateAdd(mm, i, @StartDate),
interval,
case when (datediff(mm, @StartDate, m.d)) % interval = (interval - 1) then 1 else 0 end,
m.kpiid
from
mycte m where m.d < @EndDate
)
select * from mycte where p = 1 and d <=@EndDate order by kpiid, d