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:00
,INTERVAL 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
答
在单个查询有点棘手,但此查询应该工作:
-------------- 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
and where it is 48?或72?我想在这里冒出巨大的开关 – 2010-11-11 11:17:03
'48'或'72'是什么,你为什么认为他们应该在这里? – Quassnoi 2010-11-11 11:19:00
小时添加为间隔。因为t_ending是DATETIME,而不是TIME – 2010-11-11 11:22:06