2014-12-08 5 views
0

У меня есть таблица с 20 столбцами, и я хочу заполнить последний столбец каждой строки разницей между значением этой строки (для этого столбца) за вычетом стоимости предыдущей строки для одной и той же колонки .. (если время на текущей строке выше, чем время на предыдущей строке)MySQL - Обновить таблицу и установить значение столбца, равное разным значениям текущей строки минус предыдущее значение строки

update tbl set column_with_differences = 
    (select case when (a.columnWithValueOnSameRow-b.columnWithValueOnPreviousRow) is null 
    then a.columnWithValueOnSameRow else a.columnWithValueOnSameRow-b.columnWithValueOnPreviousRow end  
as tot 
    from tbl a left join 
    tbl b 
    on a.time > b.time); 

столбцы с значениями и время - варчар (10).

Я получаю ошибку MySQL

ERROR 1093 (HY000): You can't specify target table 'tbl' for update in FROM clause 

Я знаю, что это нормально, чтобы получить эту ошибку, так как я пытающийся обновить таблицу, выбирая из него ..

Любой способ избежать этого ошибка и фактическое обновление значений в таблице с различиями текущей строки минус предыдущая строка?

Большое спасибо.

EDIT:

Мой плохо, я забыл упомянуть, что у меня есть столбец даты, а также уникальный идентификатор для каждой строки ...

+0

Берегись: MySQL содержит * не присущая концепции * порядка строк. Запрос SELECT без предложения ORDER BY может возвращать строки в наборе результатов в любом порядке. Поэтому, если вы хотите идентифицировать «предыдущую» строку в любой строке, вам нужно начать с заказа. Если вы используете «заказ по умолчанию», что бы это ни случилось, * вы будете сожалеть *, когда ваша таблица станет больше. –

ответ

0

Это немного сложнее. В select запросе, вы можете использовать переменные или сделать следующее, чтобы получить предыдущее значение,

select tbl.*, 
     (select prev.col 
     from tbl prev 
     where prev.time < tbl.time 
     order by time desc 
     limit 1 
     ) as prev_col 
from tbl; 

Это предполагает, что столбец time является столбец упорядочения. Вы можете сделать обновление путем присоединения назад к этому, опять же, с предположением - что time однозначно идентифицирует каждую строку:

update tbl t join 
     (select tbl.*, 
       (select prev.col 
       from tbl prev 
       where prev.time < tbl.time 
       order by time desc 
       limit 1 
      ) as prev_col 
     from tbl 
     ) tt 
     on tt.time = t.time 
    set t.diff = t.col - tt.prev_col; 
+0

Привет, Гордон, спасибо за ваш ответ. Я забыл упомянуть, что каждая строка также имеет дату и уникальный идентификатор, поэтому строка может иметь одно и то же время, но у них будут разные даты. Возможно, это может помочь вам с запросом ура и жаль, что не упоминал об этом в моем первоначальном сообщении , – adrCoder