计算特定年份中两个日期之间的日期数
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)
我正在努力解决这个问题,但它快把我逼疯了!如何在 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)