计算从start_date到end_date或月末的天数

时间:2017-10-25 19:25:11

标签: sql mariadb

使用datediff()我可以计算两个日期之间的天数,但我如何计算较晚日期或月末与开始日期之间的天数?

CREATE TABLE table1 (id int, start_date datetime, end_date datetime, jan int);

INSERT INTO table1 (id, start_date, end_date) VALUES 
(1, '2016-12-12', '2017-01-17'), 
(2, '2017-01-10', '2017-01-10'), 
(3, '2017-01-10', '2017-02-10'), 
(4, '2017-01-03', '2017-02-03'),
(5, '2016-12-03', '2017-02-03');

如果我跑:

select id, month(start_date) as month, datediff(end_date, start_date) as diff
from table1;

它返回

id  month   diff
1   12      36
2   1       0
3   1       31
4   1       31
5   12      62

但我希望它返回:

id  month   diff
1   12      19
5   12      28
1   1       17
2   1       0
3   1       21
4   1       28
5   1       31
3   2       10
4   2       3
5   2       3

我试图在一个月内获得按月发生事件的天数。

我创建了一个单独的查询来更新带有值的新列,但理想情况下它不应该有新列,因为我需要为每个月 - 月组合添加几个新列,每年每月需要一个新列组合:

update table1 set jan= case 
when start_date >= "2017-01-01" and end_date <= last_day("2017-01-01") then datediff(end_date, start_date)+1
when start_date >= "2017-01-01" and start_date <= last_day("2017-01-01") and end_date > last_day("2017-01-01") then datediff(last_day("2017-01-01"), start_date)+1
when start_date < "2017-01-01" and end_date between "2017-01-01" and last_day("2017-01-01") then datediff(end_date, "2017-01-01")+1
when start_date < "2017-01-01" and end_date > last_day("2017-01-01") then day(last_day("2017-01-01"))
else null
end;

2 个答案:

答案 0 :(得分:2)

你的问题将会出现多行...所以让我们采取不同的策略。

如果您有一个日历表,这最终会变得微不足道:一个带有每行行的表(以及一堆单独的列和索引):

SELECT Table1.id, Calendar.calendar_month, COUNT(*)
FROM Table1
JOIN Calendar
  ON Calendar.calendar_date >= start_date
     AND Calendar.calendar_date < end_date
GROUP BY Table1.id, Calendar.calendar_month
ORDER BY Table1.id, MIN(Calendar.calendar_date)

Fiddle Demo

答案 1 :(得分:0)

我不知道这是否是您正在寻找的。

select  month(start_date) as month, 
    datediff(LAST_DAY(start_date), start_date) as diff
from table1

UNION ALL

select  month(end_date) as month,
    IF(end_date < LAST_DAY(start_date), datediff(start_date, end_date), 
datediff(end_date, LAST_DAY(start_date)))
from table1;

DEMO