2017-05-08 177 views
0

我有表TableName它包含大約5,000行。它由一個product_id和一個ScheduleTime組成。試圖使用DATEADD和獲取函數不存在錯誤

我想用這個表格替換每個值ScheduleTime,不管它現在是什麼。每條記錄的新值ScheduleTime應設置爲前一記錄後分鐘的提名值,但有以下例外情況。如果代名人ScheduleTime發生在22:30:00之後或05:00:00之前(即太晚或太早),則應將其設置爲下一個可用日期時間。

我應該能夠指定第一個新值ScheduleTime將是什麼。

這是我使用的那一刻

#1305 - FUNCTION DatabaseName.DATEADD does not exist 

此查詢可用於創建查詢...

UPDATE TableName 
SET ScheduleTime = DATEADD(MI, ScheduleTime, 20) 
WHERE CAST(ScheduleTime AS TIME) >= '22:30:00' 
    OR CAST(ScheduleTime AS TIME) < '05:00:00'; 

但它產生此錯誤消息...表,我有...

CREATE TABLE IF NOT EXISTS TableName 
(
    product_id VARCHAR(255) NOT NULL, 
    ScheduleTime DATETIME NOT NULL 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

我使用下面的示例數據填充上表...

INSERT INTO TableName (product_id, 
         ScheduleTime) 
VALUES ('01', '2017-05-07 22:00:59'), 
     ('02', '2017-05-07 09:09:59'), 
     ('03', '2017-05-07 09:59:59'), 
     ('04', '2017-05-07 09:49:59'), 
     ('05', '2017-05-07 23:09:59'), 
     ('06', '2017-05-07 23:09:59'), 
     ('07', '2017-05-07 23:09:59'), 
     ('08', '2017-05-07 23:09:59'), 
     ('09', '2017-05-07 23:09:59'), 
     ('10', '2017-05-07 23:09:59'), 
     ('11', '2017-05-07 23:09:59'), 
     ('12', '2017-05-07 23:09:59'), 
     ('13', '2017-05-07 23:09:59'), 
     ('14', '2017-05-07 23:09:59'), 
     ('15', '2017-05-07 23:09:59'), 
     ('16', '2017-05-07 23:09:59'), 
     ('17', '2017-05-07 23:09:59'), 
     ('18', '2017-05-07 23:09:59'), 
     ('19', '2017-05-07 23:09:59'), 
     ('20', '2017-05-07 23:09:59'); 
+0

嘗試'DATE_ADD(ScheduleTime,間隔的20分鐘)'(注意'_')。請閱讀https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-add。 – toonice

+0

另外,「MI」是什麼意思? – toonice

+0

@toonice MI被靜置分鐘,當我使用'UPDATE數據庫 SET ScheduleTime = DATE_ADD(ScheduleTime,INTERVAL 20 MINUTE) 其中CAST(ScheduleTime作爲時間)<'22:30:00' 或CAST(ScheduleTime隨着時間的)> = '05:00:00'; '它不會給我錯誤,但它也不會改變表中的任何內容 – Schwann

回答

1

請通過每個記錄循環,增加20minutes到對前一個記錄的ScheduleTime字段中的值嘗試以下...

SET @workingScheduleTime := (SELECT DATE_ADD('2017-05-06 22:00:59', INTERVAL -20 MINUTE)); 
UPDATE TableName 
JOIN (SELECT product_id, 
       CASE 
        WHEN TIME(DATE_ADD(@workingScheduleTime, INTERVAL 20 MINUTE)) NOT BETWEEN '05:00:01' and '22:29:59' THEN 
         @workingScheduleTime := DATE_ADD(TIMESTAMP(DATE(@workingScheduleTime), '05:00:01'), INTERVAL 1 DAY) 
        ELSE 
         @workingScheduleTime := DATE_ADD(@workingScheduleTime, INTERVAL 20 MINUTE) 
       END AS ScheduleTime 
     FROM TableName 
    ) AS redatedList ON TableName.product_id = redatedList.product_id 
SET TableName.ScheduleTime = redatedList.ScheduleTime; 

此通過作品的解決方案。它還允許指定初始值ScheduleTime。因此,我們需要開始工作值ScheduleTime20minutes之前我們的初始值,以便循環的第一次迭代將返回我們的初始值。因此,我的解決方案開始與聲明...

SET @workingScheduleTime := (SELECT DATE_ADD('2017-05-06 22:00:59', INTERVAL -20 MINUTE)); 

隨着我們的工作價值從而初始化我一直在使用基於在MySQL - UPDATE query based on SELECT Query發現Eric的解決方案SELECT語句實現表TableNameUPDATE。聲明如下...

UPDATE TableName 
JOIN (SELECT product_id, 
       CASE 
        WHEN TIME(DATE_ADD(@workingScheduleTime, INTERVAL 20 MINUTE)) NOT BETWEEN '05:00:01' and '22:29:59' THEN 
         @workingScheduleTime := DATE_ADD(TIMESTAMP(DATE(@workingScheduleTime), '05:00:01'), INTERVAL 1 DAY) 
        ELSE 
         @workingScheduleTime := DATE_ADD(@workingScheduleTime, INTERVAL 20 MINUTE) 
       END AS ScheduleTime 
     FROM TableName 
    ) AS redatedList ON TableName.product_id = redatedList.product_id 
SET TableName.ScheduleTime = redatedList.ScheduleTime; 

本聲明基於的product_id他們共同的價值以下子查詢的結果執行TableNameINNER JOIN之間的一個實例啓動...

SELECT product_id, 
     CASE 
      WHEN TIME(DATE_ADD(@workingScheduleTime, INTERVAL 20 MINUTE)) NOT BETWEEN '05:00:01' and '22:29:59' THEN 
       @workingScheduleTime := DATE_ADD(TIMESTAMP(DATE(@workingScheduleTime), '05:00:01'), INTERVAL 1 DAY) 
      ELSE 
       @workingScheduleTime := DATE_ADD(@workingScheduleTime, INTERVAL 20 MINUTE) 
      END AS ScheduleTime 
FROM TableName 

這子查詢爲TableName中的每個記錄選擇product_id的值,然後檢查工作值的下一個值是否將在發起人禁止的時間範圍內發生爲太晚/太早。如果確實如此,則CASE聲明選擇下一個可接受的時間(第二天的05:00:01)。如果被提名人的價值在可接受的時間範圍內,則由CASE聲明選擇。工作值更新

然後將CASE語句選擇的值選爲子查詢的新值ScheduleTime

如上所述,子查詢的結果然後以這樣的方式加入到TableName中,使得每個現有記錄TableName有效地具有它附加的新值。 SET聲明使用此新建立的關係將每個現有值ScheduleTime更改爲其相應的新值。

這個答案對利用問題的CREATE聲明和填充使用下面的腳本創建數據測試...

INSERT INTO TableName (product_id, 
         ScheduleTime) 
VALUES ('01', '2017-05-07 22:00:59'), 
     ('02', '2017-05-07 09:09:59'), 
     ('03', '2017-05-07 09:59:59'), 
     ('04', '2017-05-07 09:49:59'), 
     ('05', '2017-05-07 23:09:59'), 
     ('06', '2017-05-07 23:09:59'), 
     ('07', '2017-05-07 23:09:59'), 
     ('08', '2017-05-07 23:09:59'), 
     ('09', '2017-05-07 23:09:59'), 
     ('10', '2017-05-07 23:09:59'), 
     ('11', '2017-05-07 23:09:59'), 
     ('12', '2017-05-07 23:09:59'), 
     ('13', '2017-05-07 23:09:59'), 
     ('14', '2017-05-07 23:09:59'), 
     ('15', '2017-05-07 23:09:59'), 
     ('16', '2017-05-07 23:09:59'), 
     ('17', '2017-05-07 23:09:59'), 
     ('18', '2017-05-07 23:09:59'), 
     ('19', '2017-05-07 23:09:59'), 
     ('20', '2017-05-07 23:09:59'); 

我的代碼,結果被證實由提問者爲宜。

進一步閱讀

https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_between(對MySQL的BETWEENNOT BETWEEN運營商)

https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_date(對MySQL的DATE()功能)

https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-add(對MySQL的DATE_ADD()功能)

https://dev.mysql.com/doc/refman/5.7/en/set-statement.html(上MySQL的的SET語句)

https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_time(對MySQL的TIME()功能)

https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_timestamp(對MySQL的TIMESTAMP()功能)

https://dev.mysql.com/doc/refman/5.7/en/update.html(對MySQL的UPDATE語句)

+0

感謝您花費數小時的時間爲我解決這個問題。我不能說我多麼感激這一點。該代碼完美無瑕地工作,它甚至可以選擇定義自定義開始時間和日期。 – Schwann

+0

不客氣。樂意效勞。我將很快添加一個解釋。 – toonice

+0

添加說明。此外,還發現了一個錯誤。之前,當它在被禁止的時間範圍內發現被提名人ScehduleTime值時,它將時間分量設置爲05:00:01,並將日期分量設置爲*相同*日,而不是*下一天*有。此錯誤現已在我的答案中得到糾正。如果這造成了不便,我很抱歉。 – toonice

相關問題