首页 文章

SQL Server:列出范围之间的月份

提问于
浏览
0

我正在尝试计算金融对冲的 Value ,但我希望输入尽可能简单 . 因此,例如,我在2017年2月1日至12月31日期间签订了一份 Contract ,每月数量为1,000(并不总是这个日期范围,可能是1个月或3年) 3美元的价格 . 我想在4列中只输入1行数据:[音量],[开始],[结束],[打击] .

问题是我需要将2017年的数据乘以一个价格而将2018年的数据乘以不同的价格 . 简单的答案是输入2017年的行和2018年的行,但我不想这样做,因为我可能有50个或更多的 Contract 进入,我想做尽可能少的输入 .

我会从价格表中使用两列[年],[价格] . 它看起来像[2017],[4.50]和[2018],[5.25] . 如果它有助于简化事情,我可以很容易地将其修改为每月而不是年度 .

我需要最终的计算方法是:

2017: 11,000 * (3 - 4.50) = -$16,500
2018: 12,000 * (3 - 5.25) = -$27,000
Total value = -$43,500

所以我的问题是,如何才能获得该范围内每年的月数?

我希望输出类似于

2017, 11
2018, 12

2 回答

  • 1

    日历表在这种情况下会很有帮助,那里有很多示例脚本,这里有一个:https://www.mssqltips.com/sqlservertip/4054/creating-a-date-dimension-or-calendar-table-in-sql-server/

    您也可以在 price 表中使用年份和月份并加入范围,可以使用整数类型 Year_Month_Int 字段'201601,201602,201603 ......

    然后:

    SELECT *
    FROM contracts c
    JOIN prices p
      ON p.Year_Month_Int BETWEEN (YEAR(c.start)*100)+MONTH(c.start) AND (YEAR(c.end)*100)+MONTH(c.end)
    

    如果在 contracts 表中包含 startend 的整数版本年 - 月,则可以简化 JOIN 条件 .

  • 0

    关于如何计算范围中的月数的另一种变体是:

    Build :

    create table soTest(
      id integer not null auto_increment,
      start_date datetime,
      end_date datetime,
      primary key (id)
    );
    
    insert into soTest (start_date, end_date) values 
        ('2017-02-01 00:00:00','2018-12-31 00:00:00');
    

    查询:

    select distinct case when extract(year from start_date) = yr 
                then format(datediff(concat(yr,'-12-31'), start_date)/30,0)
                else format(datediff(end_date, concat(yr,'-01-01'))/30,0) end as qtyMonths,
           yr
      from (select s.*, extract(year from start_date) yr from soTest s
             union all
            select s.*, extract(year from end_date) yr from soTest s
           ) a;
    

    结果:

    qtyMonths   yr
      11       2017
      12       2018
    

    请注意,此技术仅计算一个注册表的月份 . 要从 Contract 中获取数据,您必须使用数据集表加入此数据 .

相关问题