指定时间范围内两个日期之间的经过时间

时间:2017-01-24 20:28:28

标签: mysql sql

我有一个带有TIMESTAMP列的MYSQL表'开始'和一个TIMESTAMP栏'结束'我想返回开始和结束之间的分钟数(结束总是在开始之后)。通常我只是使用' TIMESTAMPDIFF()'但是这次我需要在上午9点到晚上22点之间得到分钟。

如果某行有一个开始2017-01-01 07:15:00'结束' 2017-01-02 11:30:00' - 经过的时间应为15.5小时(930分钟)。

我很难找到一个体面的方式来做这件事,我在线搜索还没有找到我想要的东西。有人可以帮助我吗?

编辑:

CREATE TABLE date_ranges (
Start TIMESTAMP,
End TIMESTAMP
);

INSERT INTO date_ranges VALUES('2017-01-01 07:15:00','2017-01-02 11:30:00');

我想出了这个:

SELECT Start, End, TIMESTAMPDIFF(MINUTE, Start, End) AS MinutesElapsed
FROM date_ranges;

我错过了仅在指定时间范围(上午9点至晚上22点)计算以分钟为单位的时间的部分。有什么想法吗?

4 个答案:

答案 0 :(得分:0)

你走了:

<div>

660 = 22:00至09:00(11小时)之间的分钟数

这是 SQL Fiddle

答案 1 :(得分:0)

它不是很简洁,但这应该可以给你想要的结果:

select started_at,ended_at,
  (case 
  when date(ended_at) = date(started_at)
  then 
    timestampdiff(
      minute,
      greatest(started_at,concat(date(started_at),' 09:00:00')),
      least(ended_at,concat(date(ended_at),' 22:00:00')) 
    )
  else
    timestampdiff(
      minute,  
      least(greatest(started_at,concat(date(started_at),' 09:00:00')),concat(date(started_at),' 22:00:00')),
      concat(date(started_at),' 22:00:00')
    )
    + 
    timestampdiff(
      minute,  
      concat(date(ended_at),' 09:00:00'),
      greatest(least(ended_at,concat(date(ended_at),' 22:00:00')),concat(date(ended_at),' 09:00:00'))
    )    
    + ((datediff(ended_at,started_at)-1)*780) 
  end) as total_minutes
from your_table;

答案 2 :(得分:0)

--Generating all dates in 2017.   

CREATE TABLE CALENDAR AS --Use a different table name if CALENDAR already exists
SELECT '2017-12-31 09:00:00' - INTERVAL c.number DAY AS start_datetime,'2017-12-31 22:00:00' - INTERVAL c.number DAY AS end_datetime
FROM (SELECT singles + tens + hundreds number FROM 
(SELECT 0 singles
UNION ALL SELECT   1 UNION ALL SELECT   2 UNION ALL SELECT   3
UNION ALL SELECT   4 UNION ALL SELECT   5 UNION ALL SELECT   6
UNION ALL SELECT   7 UNION ALL SELECT   8 UNION ALL SELECT   9
) singles JOIN 
(SELECT 0 tens
UNION ALL SELECT  10 UNION ALL SELECT  20 UNION ALL SELECT  30
UNION ALL SELECT  40 UNION ALL SELECT  50 UNION ALL SELECT  60
UNION ALL SELECT  70 UNION ALL SELECT  80 UNION ALL SELECT  90
) tens  JOIN 
(SELECT 0 hundreds
UNION ALL SELECT  100 UNION ALL SELECT  200 UNION ALL SELECT  300
UNION ALL SELECT  400 UNION ALL SELECT  500 UNION ALL SELECT  600
UNION ALL SELECT  700 UNION ALL SELECT  800 UNION ALL SELECT  900
) hundreds
ORDER BY number DESC) c  
WHERE c.number BETWEEN 0 and 364
;
--End of table creation

--Actual query begins here
SELECT D.`START`,
       D.`END`,
       SUM(TIMESTAMPDIFF(MINUTE,GREATEST(D.`START`,C.START_DATETIME), LEAST(D.`END`,C.END_DATETIME))) AS TOTAL_TIME
FROM CALENDAR C
LEFT JOIN DATE_RANGES D ON DATE(C.START_DATETIME) >= DATE(D.`START`)
AND DATE(C.START_DATETIME) <= DATE(D.`END`)
WHERE D.`START` IS NOT NULL
  AND D.`END` IS NOT NULL
GROUP BY D.`START`,
         D.`END`
;
  • Construct a calendar table,其中包含指定年数的日期。每个日期的开始时间为09:00,结束时间为22:00。
  • 在此表上进行左连接,以便从日期范围表中为每个日期获取一行。
  • 每天总结差异以获得总工作时间。

Sample Demo

答案 3 :(得分:0)

    Day 1         Day 2        Day 3  
|--********--|--********--|--********--|  
    |__________________________|  

问题是,恕我直言,要知道第一天多少分钟,以及最后一天多少分钟,中间天有780分钟。

我使用子查询只是为了帮助进行中间计算。

select
    if(hour(t1) < 9, date(t1) + interval 9 hour , t1) as tIni1,
    date(t1) + interval 22 hour as tFin1,
    date(t2) + interval 9 hour as tIni2,
    if(hour(t2) >  22, date(t2) + interval 22 hour, t2) as tFin2,
    TIMESTAMPDIFF(day, date(t1), date(t2)) numDays
from
    tdt

tIni1和tFin1是第一天的时间段,而tIni2,tFin2是最后一天的时间段,显然第一天和最后一天可以是相同的。

然后计算第一天的分钟数+第二天的分钟数+每个中间日的780分钟数。

select numDays, tIni1, tFin1, tIni2, tFin2,
    if (numDays = 0,
        TIMESTAMPDIFF(minute, tIni1, tFin2),
            TIMESTAMPDIFF(minute, tIni1, tFin1)
            + TIMESTAMPDIFF(minute, tIni2, tFin2)
            + (numDays - 1) * 780
        ) as Minutes
from (
        select
            if(hour(t1) < 9, date(t1) + interval 9 hour , t1) as tIni1,
            date(t1) + interval 22 hour as tFin1,
            date(t2) + interval 9 hour as tIni2,
            if(hour(t2) >  22, date(t2) + interval 22 hour, t2) as tFin2,
            TIMESTAMPDIFF(day, date(t1), date(t2)) numDays
        from
            tdt
    ) ti
; 

在此处试试:http://rextester.com/GDHAB78973