Расчет месяца между 2 датами по году - PullRequest
0 голосов
/ 23 апреля 2019

Нужна помощь в понимании того, как рассчитать месяцы по годам между двумя датами, может рассчитывать месяцы между датами, но не по годам

ID  StartDate   Enddate
1   1/1/2016    4/23/2019
2   1/1/2016    4/30/2017
3   1/1/2016    12/31/2018
4   1/1/2017    4/23/2019
5   5/20/2017   11/30/2017



ID  StartDate   Enddate        2016 2017  2018  2019
1   1/1/2016    4/23/2019        12   12    12     4
2   1/1/2016    4/30/2017        12    4     0     0
3   1/1/2016    12/31/2018       12   12    12     0
4   1/1/2017    4/23/2019         0   12    12     4
5   5/20/2017   11/30/2017        0    7     0     0

Ответы [ 2 ]

0 голосов
/ 23 апреля 2019

Если у вас есть годы в таблице, вы можете сделать такой динамический круг, это избавит вас от объявления столбцов вручную:

CREATE TABLE #Data (ID int, StartDate date, EndDate date);
CREATE TABLE #Year (y int);

SET DATEFORMAT MDY;

insert into #Data 
values 
    (1, '1/1/2016','4/23/2019'),
    (2, '1/1/2016','4/30/2017'),
    (3, '1/1/2016','12/31/2018'),
    (4, '1/1/2017','4/23/2019'),
    (5, '5/20/2017','11/30/2017')
;

insert into #Year
values
    (2016),
    (2017),
    (2018),
    (2019)
;

DECLARE 
    @PivotColumnNames AS NVARCHAR(MAX),
    @DynamicPivotQuery AS NVARCHAR(MAX);

SELECT 
    @PivotColumnNames = ISNULL(@PivotColumnNames + ',','') + QUOTENAME(Y)
FROM 
    #Year;

SELECT
    @DynamicPivotQuery =
'SELECT
    ID,
    StartDate,
    EndDate,' 
    + @PivotColumnNames + 
'FROM
(
    select 
        ID,
    StartDate,
    EndDate, 
        Y,
        case 
            when StartDate >= DATEFROMPARTS(Y+1, 1, 1) or EndDate < DATEFROMPARTS(Y, 1, 1) then 0
            when StartDate < DATEFROMPARTS(Y, 1, 1) and EndDate >= DATEFROMPARTS(Y+1, 1, 1) then 12
            when StartDate >= DATEFROMPARTS(Y, 1, 1) and EndDate >= DATEFROMPARTS(Y+1, 1, 1) then 13 - MONTH(StartDate)
            when StartDate < DATEFROMPARTS(Y, 1, 1) then month(EndDate)
            else MONTH(EndDate) + 1 - MONTH(StartDate) 
        end M
    from
        #Data, #Year
) as SourceTable
PIVOT
(
    SUM(M)
    FOR Y IN ('
    + @PivotColumnNames + 
    ')
) as PivotTable';

SELECT @DynamicPivotQuery;

EXEC sp_executesql @DynamicPivotQuery;

DROP TABLE #Data, #Year;
0 голосов
/ 23 апреля 2019

Считать такие интервалы сложно в SQL Server.Было бы намного проще, если бы база данных поддерживала least() и greatest().Вот подробный подход:

select id, startdate, enddate,
       (case when startdate >= '2017-01-01' or enddate < '2016-01-01' then 0
             when startdate < '2016-01-01' and enddate >= '2017-01-01' then 12
             when startdate >= '2016-01-01' and enddate >= '2017-01-01' then 13 - month(startdate)
             when startdate < '2016-01-01' then month(enddate)
             else month(enddate) + 1 - month(startdate) 
        end) as months_2016,
       (case when startdate >= '2018-01-01' or enddate < '2017-01-01' then 0
             when startdate < '2017-01-01' and enddate >= '2018-01-01' then 12
             when startdate >= '2017-01-01' and enddate >= '2018-01-01' then 13 - month(startdate)
             when startdate < '2017-01-01' then month(enddate)
             else month(enddate) + 1 - month(startdate) 
        end) as months_2017,
       (case when startdate >= '2019-01-01' or enddate < '2018-01-01' then 0
             when startdate < '2018-01-01' and enddate >= '2019-01-01' then 12
             when startdate >= '2018-01-01' and enddate >= '2019-01-01' then 13 - month(startdate)
             when startdate < '2018-01-01' then month(enddate)
             else month(enddate) + 1 - month(startdate) 
        end) as months_2018
from t;

Это в основном обрабатывает различные условия относительно того, является ли дата начала до, в течение или после рассматриваемого года и одинаковой для даты окончания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...