【问题标题】:Count number of times a specific day\date occurs between two dates计算特定日期\日期在两个日期之间出现的次数
【发布时间】:2018-11-29 00:20:07
【问题描述】:

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

这是我想要得到的结果集:

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

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

01/01/2015 至 31/12/2018 = 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

最好的方法是什么?

【问题讨论】:

  • 样本数据和期望的结果真的很有帮助。
  • 样本数据和结果在查询上方的结果集中。它没有标题,但第一个日期是开始日期,第二个日期是结束日期,数字是跨越 01/04/xx 日期的数量。抱歉,我应该把它放在整洁的桌子上。

标签: sql tsql


【解决方案1】:

您可以使用外部应用来执行类似的操作来加入您的周期表

;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

【讨论】:

  • 感谢您的回复。我最终采用的解决方案是有一个单独的日历表,其中包含一个期间的列。从结束期间减去开始期间得出更改的数量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-06
  • 2013-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-22
  • 2021-05-25
相关资源
最近更新 更多