2017-01-28 2 views
0

Я пытаюсь вычислить значения финансовых хеджирования, но я хочу, чтобы вход был как можно более простым. Так, например, у меня есть контракт с количеством 1000 в месяц с 1/1/2017 по 12/31/2018 (это не всегда будет этот диапазон дат, это может быть 1 месяц или 3+ года) с цена исполнения $ 3. Я хочу ввести только 1 строку данных в 4 столбца: [Volume], [Start], [End], [Strike].SQL Server: список месяцев между диапазонами

Проблема заключается в том, что мне нужно умножить данные 2017 по одной цене и 2018 по другой цене. Легким ответом было бы ввести строку для 2017 года и строку для 2018 года, но я не хочу этого делать, потому что у меня может быть 50 или более контрактов для входа, и я хочу сделать как можно меньше ввода.

Я бы использовал две колонки [год], [Цена] из ценового стола. Это будет выглядеть как [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 
+0

Все, что вы хотите, - подсчитать количество месяцев в году в диапазоне дат? –

+0

Контракты всегда начинаются/заканчиваются в начале/конце месяца, или они могут быть в середине месяца? –

+0

@JorgeCampos Да, я считаю, что это все, что я хочу. – FilburtShellbach

ответ

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) 

Если вы включили целочисленную версию года-месяц для start и end в contracts таблицы можно упростить JOIN критерии.

+0

Спасибо! Я сделаю это в понедельник. – FilburtShellbach

0

Другой вариант о том, как подсчитать количество месяцев в диапазоне будет:

Установка:

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 

Знайте, что t его техника будет учитывать только месяцы в случае одного реестра. Чтобы получить данные из ваших контрактов, вам придется ПРИСОЕДИНИТЬСЯ к этому с помощью своих таблиц набора данных.

Смежные вопросы