sql - 添加时间间隔跳过一定的时间段

问题描述:

我有一个mySql查询,它为datetime字段添加了一定的时间间隔。sql - 添加时间间隔跳过一定的时间段

UPDATE table T 
    SET T.ending = DATE_ADD(T.ending, INTERVAL T.hours * 3600 * some_other_variable_factors SECONDS)) 

现在,我需要检测是否有新的结束时间在几个小时之间(假设20:00至06:00),这应该从计算中排除。

即,如果以前的结局是今天19:58我们加了4分钟,新的结局应该是明天06:02

另外的困难是添加的时间量可能大于24小时。 所以,如果旧的结局是今天,19.00,我们将24小时,新的结局应该后天是天,15.00(这听起来是一个非常糟糕的电影的标题;)

有没有办法在实现这一目标MySQL的?在一个查询中?我也在考虑存储过程,但我没有任何经验。

一些测试数据:

CREATE TABLE IF NOT EXISTS `tt` (
     `source` datetime NOT NULL, 
     `hours` int(11) NOT NULL, 
     `off_start` int(11) NOT NULL, 
     `off_long` int(11) NOT NULL, 
     `correct` datetime NOT NULL  
    ) ENGINE=InnoDb; 


    INSERT INTO `tt` (`source`, `hours`, `off_start`, `off_long`, `correct`) VALUES 
    ('2010-11-11 12:00:00', 1, 20, 10, '2010-11-11 13:00:00'), 
    ('2010-11-11 19:00:00', 1, 20, 10, '2010-11-12 06:00:00'), 
    ('2010-11-11 19:00:00', 2, 20, 10, '2010-11-12 07:00:00'), 
    ('2010-11-11 19:00:00', 3, 20, 10, '2010-11-12 08:00:00'), 
    ('2010-11-11 19:00:00', 24, 20, 10, '2010-11-13 15:00:00'), 
    ('2010-11-11 19:00:00', 48, 20, 10, '2010-11-15 11:00:00'), 
    ('2010-11-11 19:00:00', 72, 20, 10, '2010-11-17 07:00:00'); 

SELECT CASE 
     WHEN HOUR((t_ending + INTERVAL some_other_variable_factors HOUR) - INTERVAL 20 HOUR) < 10 THEN 
       t_ending + INTERVAL some_other_variable_factors HOUR + INTERVAL 10 HOUR 
     ELSE 
       t_ending + INTERVAL some_other_variable_factors HOUR 
     END 
FROM mytable 

INTERVAL 20 HOUR意味着你的截止时间开始于20:00INTERVAL 10 HOUR意味着持续10小时(20:00直到06:00)。相应地调整。

更新:

SET @hours = 54; 

SELECT CAST('2010-01-01 15:00:00' + INTERVAL @hours HOUR AS DATETIME); 

-- 
2010-01-03 21:00:00 


SELECT CASE 
     WHEN HOUR(CAST('2010-01-01 15:00:00' + INTERVAL @hours HOUR AS DATETIME) - INTERVAL 20 HOUR) < 10 THEN 
       CAST('2010-01-01 15:00:00' + INTERVAL @hours HOUR + INTERVAL 10 HOUR AS DATETIME) 
     ELSE 
       CAST('2010-01-01 15:00:00' + INTERVAL @hours HOUR AS DATETIME) 
     END; 

-- 
2010-01-04 07:00:00 
+0

and where it is 48?或72?我想在这里冒出巨大的开关 – 2010-11-11 11:17:03

+0

'48'或'72'是什么,你为什么认为他们应该在这里? – Quassnoi 2010-11-11 11:19:00

+0

小时添加为间隔。因为t_ending是DATETIME,而不是TIME – 2010-11-11 11:22:06

在单个查询有点棘手,但此查询应该工作:

 
-------------- 
SELECT source, correct, hours_to_end, (source + INTERVAL hours_to_end HOUR) ending 
FROM (
    SELECT source, correct 
     , LEAST(hours, hours_to_off) 
      + (((hours_left - MOD(hours_left, on_long))/on_long) * 24 
      + off_long 
      + MOD(hours_left, on_long)) * overlap hours_to_end 
    FROM (
     SELECT source, correct, hours, on_long, off_long, hours_to_off 
      , GREATEST(0, hours - hours_to_off) hours_left 
      , IF(hours - hours_to_off >= 0, 1, 0) overlap 
     FROM (
      SELECT source, correct, hours, off_long 
       , (24 - off_long) on_long 
       , HOUR(TIMEDIFF(DATE(source) + INTERVAL off_start HOUR, source)) hours_to_off 
      FROM tt 
     ) t 
    ) t 
) t 
-------------- 

+---------------------+---------------------+--------------+---------------------+ 
| source    | correct    | hours_to_end | ending    | 
+---------------------+---------------------+--------------+---------------------+ 
| 2010-11-11 12:00:00 | 2010-11-11 13:00:00 |  1.0000 | 2010-11-11 13:00:00 | 
| 2010-11-11 19:00:00 | 2010-11-12 06:00:00 |  11.0000 | 2010-11-12 06:00:00 | 
| 2010-11-11 19:00:00 | 2010-11-12 07:00:00 |  12.0000 | 2010-11-12 07:00:00 | 
| 2010-11-11 19:00:00 | 2010-11-12 08:00:00 |  13.0000 | 2010-11-12 08:00:00 | 
| 2010-11-11 19:00:00 | 2010-11-13 15:00:00 |  44.0000 | 2010-11-13 15:00:00 | 
| 2010-11-11 19:00:00 | 2010-11-15 11:00:00 |  88.0000 | 2010-11-15 11:00:00 | 
| 2010-11-11 19:00:00 | 2010-11-17 07:00:00 |  132.0000 | 2010-11-17 07:00:00 | 
+---------------------+---------------------+--------------+---------------------+ 

编辑:这里是一个较短的版本:

 
SELECT source, correct 
    , source 
    + INTERVAL LEAST(hours, hours_to_off) 
     + IF(hours-hours_to_off >= 0 
     ,(hours-hours_to_off-MOD(hours-hours_to_off, on_long))/on_long*24 
      + off_long + MOD(hours-hours_to_off, on_long) 
     ,0) HOUR ending 
FROM (
    SELECT source, correct, hours, off_long, (24-off_long) on_long 
     , HOUR(TIMEDIFF(DATE(source)+INTERVAL off_start HOUR, source)) hours_to_off 
    FROM tt 
) t 
; 
+1

Bagh。广告。 – thomaspaulb 2010-11-18 10:40:34

这是mine:

CREATE PROCEDURE do_update() 
BEGIN 

DECLARE @offhoursperday, @hours, @days, @remaininghours INT 
DECLARE @offhoursstart, @offhoursend TIME 

SET @offhoursstart = CAST('22:00' AS TIME) 
SET @offhoursend = CAST('06:00' AS TIME) 
SET @hours = 54 
SET @days = @hours/(24 - @offhoursperday) 
SET @remaininghours = @hours % (24 - @offhoursperday) 

UPDATE table T 
    SET T.ending = 
    CASE 
     WHEN ((HOUR(TIMEDIFF(@offhoursstart, TIME(T.ending))) + 24) % 24) < @remaininghours 
     THEN DATE_ADD(DATE_ADD(T.ending, INTERVAL @days DAY), INTERVAL @remaininghours HOUR) 
     ELSE DATE_ADD(DATE_ADD(T.ending, INTERVAL @days DAY), INTERVAL (@remaininghours + @offhoursperday) HOUR) 
    END 

END