计算特定年份中两个日期之间的日期数

Calculating the number of dates in specific year, between two dates

我正在努力解决这个问题,但它快把我逼疯了!如何在 SQL 中计算特定年份中两个日期之间的天数?例如:我们有范围日期 [12/30/2016-01/05/2017]。如果我需要找出 2017 年在这个日期范围内有多少天,那就是 5 天。 SQL 是怎么做到的?

实际答案是“这取决于数据库供应商”,因为即使是简单的日期计算也有很大差异,例如

MySQL

SELECT DATEDIFF('2017-01-05','2016-12-30');

TSQL(MS SQL 服务器)

SELECT DATEDIFF ( day,'2016-12-30', '2017-01-05')

Postgres

SELECT '2017-01-05'::DATE - '2016-12-30'::DATE

火鸟 在 Postgres 中也有替代方案。

甲骨文

SELECT (date '2017-01-05') - (date '2016-12-30') from dual

在 Oracle 中也有替代方法。

火鸟

select datediff(day,cast('2016-12-30' as date),cast('2017-01-05' as date)) from rdb$database

您的请求涉及到需要操作日期,因此有必要知道是哪个数据库。

您没有指定您的 dbms,但一般来说:

  • 获取@EndDate 年的第一天,即 2017 年 1 月 1 日
  • 然后计算@FirstOfYear 和@EndDate 之间的天数差

例如在MySQL中,您可以使用MAKEDATE() to get the first of the year. Then DATEDIFF()来计算天数

SET @StartDate = '2016-12-30';
SET @EndDate = '2017-01-05';  

SELECT DateDiff(@endDate, MAKEDATE(Year(@endDate),1)) + 1 AS DaysInEndDateYear

结果:

| DaysDiffValue|
| ----------------: |
|                 5 |

如果您还需要处理@StartDate 和@EndDate 在同一年的范围:

SET @StartDate = '2017-01-05';
SET @EndDate = '2017-03-14';  

SELECT CASE WHEN Year(@StartDate) = Year(@EndDate) THEN DateDiff(@EndDate, @StartDate) + 1
            ELSE DateDiff(@endDate, MAKEDATE(Year(@endDate),1)) + 1
       END AS DaysInEndDateYear

结果:

| DaysInEndDateYear |
| ----------------: |
|                69 |

db<>fiddle here

您没有指定您的 DBMS,但是如果您使用 PostgreSQL,您可以使用 date range 来计算它。

您的问题本质上是给定日期范围与“2017”范围之间的交集长度:

select daterange('2016-12-30', '2017-01-05', '[]') * daterange('2017-01-01', '2018-01-01')

日期范围默认排除上限,这就是为什么“2017”的范围将 2018-01-01 指定为(排除的)上限。 * 运算符计算这两个范围之间的 intersection。我假设你想 include 2017-01-05 include 2017-01-05 include include 2017-01-05 include 2017-01-05 include '[]'.

然后通过从上限减去下限来计算长度:

select upper(result) - lower(result) as days
from ( 
   select daterange('2016-12-30', '2017-01-05', '[]') * daterange('2017-01-01', '2018-01-01')
) t(result)