计算特定日期\日期在两个日期之间发生的次数

时间:2018-11-28 15:59:28

标签: sql tsql

我有一份合同价格,每年4月1日发生变化。合同的开始日期和结束日期可能会跨越多个价格变动,因此我最初想计算合同开始日期和合同结束日期之间的变动。

这是我要获取的结果集:

2017年1月4日至2018年3月31日= 0

31/03/2018到01/04/2018 = 1

2015年1月1日至2018年12月31日= 4

当前我的查询如下(手动可怕):

SET DATEFORMAT DMY;
SELECT
Contract_ID,
 (Period_1 + Period_2 + Period_3 + Period_4 + Period_5 + Period_6 + Period_7
+ Period_8 + Period_9
 ) AS Split_Count
FROM
(
SELECT 
C.Contract_ID,
 CASE
 WHEN ('01/04/2011'BETWEEN Contract_Date_OLD AND Contract_Date_NEW) THEN 1
 ELSE 0
 END AS Period_1,
 CASE
 WHEN ('01/04/2012'BETWEEN Contract_Date_OLD AND Contract_Date_NEW) THEN 1
 ELSE 0
 END AS Period_2, 
 CASE
 WHEN ('01/04/2013'BETWEEN Contract_Date_OLD AND Contract_Date_NEW) THEN 1
 ELSE 0
 END AS Period_3,
 CASE
 WHEN ('01/04/2014'BETWEEN Contract_Date_OLD AND Contract_Date_NEW) THEN 1
 ELSE 0
 END AS Period_4,
 CASE
 WHEN ('01/04/2015'BETWEEN Contract_Date_OLD AND Contract_Date_NEW) THEN 1
 ELSE 0
 END AS Period_5,
 CASE
 WHEN ('01/04/2016'BETWEEN Contract_Date_OLD AND Contract_Date_NEW) THEN 1
 ELSE 0
 END AS Period_6,
 CASE
 WHEN ('01/04/2016'BETWEEN Contract_Date_OLD AND Contract_Date_NEW) THEN 1
 ELSE 0
 END AS Period_7,
 CASE
 WHEN ('01/04/2017'BETWEEN Contract_Date_OLD AND Contract_Date_NEW) THEN 1
 ELSE 0
 END AS Period_8,
 CASE
 WHEN ('01/04/2018'BETWEEN Contract_Date_OLD AND Contract_Date_NEW) THEN 1
 ELSE 0
 END AS Period_9
FROM Contract C

做到这一点的最佳方法是什么?

1 个答案:

答案 0 :(得分:0)

您可以使用外部应用程序来执行类似这样的操作以加入到您的周期表中

;with periods as (
    select 1 as [period], '01/04/2011' as startdate
    union all select 2 as [period], '01/04/2012'
    union all select 3 as [period], '01/04/2013'
    union all select 4 as [period], '01/04/2014'
    union all select 5 as [period], '01/04/2015'
    union all select 6 as [period], '01/04/2016'
    union all select 7 as [period], '01/04/2017'
    union all select 8 as [period], '01/04/2018'
    union all select 9 as [period], '01/04/2019'
)
select      *
from        periods
outer apply (   select      Contract_ID
                            , count(*) as Split_Count
                from        Contract
                where       startdate between Contract_Date_OLD and Contract_Date_NEW
                group by    Contract_ID) c

您可以透视此数据以查看单行中的周期计数。

select      c.Contract_ID,
            max(case when p.[period] = 1 then c.Split_Count end) as period_1,
            max(case when p.[period] = 2 then c.Split_Count end) as period_2,
            max(case when p.[period] = 3 then c.Split_Count end) as period_3,
            max(case when p.[period] = 4 then c.Split_Count end) as period_4,
            max(case when p.[period] = 5 then c.Split_Count end) as period_5,
            max(case when p.[period] = 6 then c.Split_Count end) as period_6,
            max(case when p.[period] = 7 then c.Split_Count end) as period_7,
            max(case when p.[period] = 8 then c.Split_Count end) as period_8,
            max(case when p.[period] = 9 then c.Split_Count end) as period_9
from        [periods] p
outer apply (   select      Contract_ID
                            , count(*) as Split_Count
                from        Contract
                where       startdate between Contract_Date_OLD and Contract_Date_NEW
                group by    Contract_ID) c
group by    Contract_ID

或仅获取合同的总金额。

select      c.Contract_ID,
            sum(Split_Count) as Split_Count
outer apply (   select      Contract_ID
                            , count(*) as Split_Count
                from        Contract
                where       startdate between Contract_Date_OLD and Contract_Date_NEW
                group by    Contract_ID) c
group by    Contract_ID