2010-11-11 89 views
5

我有一個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'); 

回答

3
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

2

在單個查詢有點棘手,但此查詢應該工作:

 
-------------- 
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

1

這是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