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

sql-添加跳过特定时段的时间间隔,sql,mysql,datetime,stored-procedures,time,Sql,Mysql,Datetime,Stored Procedures,Time,我有一个mySql查询,它在datetime字段中添加了一定的时间间隔 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 另一个困难是

我有一个mySql查询,它在datetime字段中添加了一定的时间间隔

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点,我们加上24小时,新的结局应该是后天15点,听起来像是一部非常糟糕的电影的标题

有没有办法在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 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 ; 这是我的:

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

它在哪里?还是72?我想证明这里有一个巨大的开关,什么是48或72,为什么你们认为他们应该在这里?作为间隔加上小时。因为t_ending是DATETIME,而不是time,所以您可以将t_ending设置为任意DATETIME,并将一些其他变量_因子设置为任意整数,包括48和72。@ts:ah,您希望关闭时间间隔相加,对吗?我没有先得到它。 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 ;
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