Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 按年份计算两个日期之间的月份_Sql_Sql Server - Fatal编程技术网

Sql 按年份计算两个日期之间的月份

Sql 按年份计算两个日期之间的月份,sql,sql-server,Sql,Sql Server,需要帮助了解如何计算两个日期之间的月份,能够计算日期之间的月份,但不能计算年份 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 201

需要帮助了解如何计算两个日期之间的月份,能够计算日期之间的月份,但不能计算年份

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

在SQL Server中,像这样计算时间间隔是很棘手的。如果数据库支持最小值和最大值,则会简单得多。下面是一个详细的方法:

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;

这基本上处理了开始日期是在相关年份之前、期间还是之后以及结束日期的不同情况。

如果表中有年份,则可以执行类似这样的动态透视,这样可以节省手动声明列的时间:

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;

总是2016年到2019年?到目前为止你尝试了什么?总是2016年到2019年日期可能会有所不同。这是否意味着如果插入第6行“2011年1月1日”、“2017年4月23日”,您会突然需要增加5列?就我而言,日期不会在2016年1月1日之前