首页 > 解决方案 > 计算SQL中两个日期之间发生了多少个月“一月”

问题描述

我需要知道在 TSQL 中的两个日期之间发生了多少一月。

即,如果包含特定年份中一月份的任何一天,那么这将计为每年 1 次,而不是每月多次。

例如,以下将给出结果 = 1

declare @date1 datetime = '2018-09-01 00:00:00.000';
declare @date2 datetime = '2019-02-01 00:00:00.000';

例如,以下将给出结果 = 1,因为 1 月有 1 天

declare @date1 datetime = '2018-09-01 00:00:00.000';
declare @date2 datetime = '2019-01-01 00:00:00.000';

例如,以下将给出结果 = 0,因为 1 月份没有天数

declare @date1 datetime = '2018-09-01 00:00:00.000';
declare @date2 datetime = '2018-11-01 00:00:00.000';

例如,以下将给出结果 = 2,因为一月出现了两次

declare @date1 datetime = '2017-09-01 00:00:00.000';
declare @date2 datetime = '2019-11-01 00:00:00.000';

标签: sql-servertsql

解决方案


尝试使用DATEDIFF()DATEPART()

您可以测试您的开始日期和结束日期是否在 1 月日期之外,然后添加 -1...

DECLARE @startdate AS DATETIME = '2015-02-01'
DECLARE @enddate   AS DATETIME = '2019-06-01'

SELECT
    DATEDIFF(yy, @startdate, @enddate) 
    + 1 
    + CASE 
        WHEN DATEPART(m, @startdate) > 1 AND 
           DATEPART(m, @enddate) > 1 
        THEN -1
        ELSE  0
    END 

但是,我不确定这在大型数据集上会有多快。如果您要将大量数据与特定日期/时间集进行比较,那么我建议您测试Squirrel's answer

要将其修改为不同的月份,只需CASE像这样更改子句...

+ CASE 
    WHEN DATEPART(m, @startdate) < 2 AND DATEPART(m, @startdate) > 2 AND 
         DATEPART(m, @enddate)   < 2 AND DATEPART(m, @enddate)   > 2 

2语句中的CASE是月份,因此只需将其更改为适当的月份编号。

如果您想为任何月份更改此设置,请为您要查找的月份编号添加一个参数...

+ CASE 
    WHEN DATEPART(m, @startdate) < @month_number AND 
         DATEPART(m, @startdate) > @month_number AND 
         DATEPART(m, @enddate)   < @month_number AND 
         DATEPART(m, @enddate)   > @month_number 

这也可以变成一个函数 (UDF)


推荐阅读