2016-07-14 2 views
2

Я следующий набор записей:Время обновления на основе предыдущих записей в MySQL

+------------------------------------------+ 
| ID | DateTimeValue  | UsedMinutes | 
| 1 | 2016-01-01 00:00:00 | 30   | 
| 2 | 2016-01-01 00:00:00 | 45   | 
| 3 | 2016-01-01 00:00:00 | 20   | 
| 4 | 2016-02-02 00:00:00 | 30   | 
| 5 | 2016-02-02 00:00:00 | 60   | 
+------------------------------------------+ 

Я хотел бы, чтобы превратить их в:

+------------------------------------------+ 
| ID | DateTimeValue  | UsedMinutes | 
| 1 | 2016-01-01 00:00:00 | 30   | 
| 2 | 2016-01-01 00:30:00 | 45   | 
| 3 | 2016-01-01 01:15:00 | 20   | 
| 4 | 2016-02-02 00:00:00 | 30   | 
| 5 | 2016-02-02 00:30:00 | 60   | 
+------------------------------------------+ 

Так на сегодняшний день значение времени должно быть увеличивается на основе предыдущей записи и поля «Используемые минуты». У моего фактического набора записей есть тысячи записей, поэтому ручная модификация не является вариантом.

Возможно ли это сделать с (единственным) запросом MySQL?

ответ

1

Вы можете дать ему попробовать:

SELECT 
t.ID, 
t.expectedTime, 
t.usedMin 
FROM 
(
    SELECT 
     ID, 
     IF(@currentDateTime <> DateTimeValue, @runningTime :='0000-00-00 00:00:00' , 1) resetting, 
     IF(@runningTime = '0000-00-00 00:00:00', DateTimeValue, @runningTime) AS expectedTime, 
     @minuteToAddNext := UsedMinutes AS usedMin, 
     @currentDateTime := DateTimeValue AS previousDateTime, 
     @runningTime := IF(@runningTime = '0000-00-00 00:00:00', DateTimeValue + INTERVAL UsedMinutes MINUTE , @runningTime + INTERVAL UsedMinutes MINUTE) AS nextRowsValue 
    FROM 
      datetimetable 
    CROSS JOIN (
      SELECT 
        @currentDateTime := '0000-00-00 00:00:00', 
        @minuteToAddNext := 0, 
        @runningTime := '0000-00-00 00:00:00' 
    ) AS var 
    ORDER BY DateTimeValue 
) AS t; 

WORKING DEMOвыходы 4 колонки (один дополнительный)

UPDATED WORKING DEMOвыходы 3 колонки, чтобы соответствовать ваше требование


Пояснение:

При сканировании каждой строки хранить значение UsedMinutes в переменной под названием @minuteToAddNext, как в запросе:

@minuteToAddNext := UsedMinutes

При сканировании следующей строки ваш f Первой задачей является добавление значения @minuteToAddNext в DateTimeValue, только если значение @minuteToAddNext было сохранено от того же dateTimeValue. Это переводится в запрос, как это:

DateTimeValue + INTERVAL IF(@currentDateTime = DateTimeValue, @minuteToAddNext , 0) MINUTE AS updatedDteTimeValue

Посмотрите, если предыдущий Роу @currentDateTime = current row's DateTimeValue, то вы получите от @minuteToAddNextIF. (Одинаковые dateTimeValue).

В противном случае IF вернет 0. Так, DateTimeValue + INTERVAL 0 MINUTE = DateTimeValue

EDIT:

Для того, чтобы обновить таблицу с теми сгенерированных datetime значениями из приведенного выше запроса на выборку вам необходимо выполнить следующий запрос:

UPDATE datetimetable DT 
INNER JOIN 
(
     SELECT 
     ID, 
     IF(@currentDateTime <> DateTimeValue, @runningTime :='0000-00-00 00:00:00' , 1) resetting, 
     IF(@runningTime = '0000-00-00 00:00:00', DateTimeValue, @runningTime) AS expectedTime, 
     @minuteToAddNext := UsedMinutes AS usedMin, 
     @currentDateTime := DateTimeValue AS previousDateTime, 
     @runningTime := IF(@runningTime = '0000-00-00 00:00:00', DateTimeValue + INTERVAL UsedMinutes MINUTE , @runningTime + INTERVAL UsedMinutes MINUTE) AS nextRowsValue 
    FROM 
      datetimetable 
    CROSS JOIN (
      SELECT 
        @currentDateTime := '0000-00-00 00:00:00', 
        @minuteToAddNext := 0, 
        @runningTime := '0000-00-00 00:00:00' 
    ) AS var 
    ORDER BY DateTimeValue 
) AS t 
ON DT.ID = t.ID 
SET DT.DateTimeValue = t.expectedTime; 
+0

Почти идеально :) Но строка с ID 3 не получает ожидаемого значения из моего примера. Это нужно взять значение из ID 2 и добавить свои минуты. Любая идея, как это решить? –

+0

Извините, я не заметил, что вы хотите получить суммарное значение времени для каждой даты. Исправлено сейчас. Пожалуйста, проверьте. @MartindeRuiter – 1000111

+0

Выглядит хорошо! Вы знаете, как это можно сделать в запросе обновления, поэтому значения в таблице будут обновляться с новыми значениями datetime? –

1

Я думаю, что это решит вашу проблему

mysql> select * from TRE; 
+------+---------------+-------------+ 
| ID | DateTimeValue | UsedMinutes | 
+------+---------------+-------------+ 
| 1 | 2016-01-01 |   30 | 
| 2 | 2016-01-01 |   45 | 
| 3 | 2016-01-01 |   20 | 
| 4 | 2016-02-02 |   30 | 
| 5 | 2016-02-02 |   60 | 
+------+---------------+-------------+ 
5 rows in set (0.00 sec) 

mysql> select TRE.*,@curRank := @curRank + UsedMinutes as SUM_time from TRE,(SELECT @curRank := 0) r ORDER BY ID; 
+------+---------------+-------------+----------+ 
| ID | DateTimeValue | UsedMinutes | SUM_time | 
+------+---------------+-------------+----------+ 
| 1 | 2016-01-01 |   30 |  30 | 
| 2 | 2016-01-01 |   45 |  75 | 
| 3 | 2016-01-01 |   20 |  95 | 
| 4 | 2016-02-02 |   30 |  125 | 
| 5 | 2016-02-02 |   60 |  185 | 
+------+---------------+-------------+----------+ 
5 rows in set (0.03 sec) 

mysql> select DATE_ADD(DateTimeValue, INTERVAL @curRank := @curRank + UsedMinutes MINUTE) from TRE,(SELECT @curRank := 0) r ORDER BY ID; 
+-----------------------------------------------------------------------------+ 
| DATE_ADD(DateTimeValue, INTERVAL @curRank := @curRank + UsedMinutes MINUTE) | 
+-----------------------------------------------------------------------------+ 
| 2016-01-01 00:30:00               | 
| 2016-01-01 01:15:00               | 
| 2016-01-01 01:35:00               | 
| 2016-02-02 02:05:00               | 
| 2016-02-02 03:05:00               | 
+-----------------------------------------------------------------------------+ 
5 rows in set (0.05 sec) 
+0

добавлен способ показать, как это сделать, если это не очень ясно, дайте мне знать –

+0

Следует учитывать дату, поэтому каждая новая дата начинается в 00:00:00. См. Мою примерную таблицу. Любая идея для этого требования? Также, как обновить таблицу с помощью SQL? –

+0

да в этом случае добавить инструкцию if, если новый набор данных curRank = 0, то вы получите то, что хотите –

Смежные вопросы