Запрос MySQL для обновления записей с увеличенной датой

я пытаюсь

  1. получить последнюю дату в базе данных и
  2. на основе этой даты обновите каждую запись с датой NULL, увеличив дату на 1 день.

Я могу получить последнюю дату, используя приведенный ниже запрос Последняя дата. Мне нужно сделать это в первую очередь, потому что даты в таблице неправильные. Если нужно, я могу запустить этот запрос, записать его вручную, а затем выполнить запрос UPDATE на основе этой даты. Я бы предпочел запустить все без ручного процесса.

Последний запрос, который у меня есть в нижней части вопроса, — это мой тестовый запрос для попытки обновить даты, однако мне не удалось заставить его работать.

Таблица (даты указаны не по порядку)

id     date
-----  ----------
10500  2013-08-18
10501  2013-08-16
10502  2013-08-17
10503  2013-08-19
10504  NULL
10505  NULL
...
11800  NULL
11801  NULL

Выбор последней даты (отправной точки для UPDATE)

SELECT date
FROM my_table
ORDER BY date DESC
LIMIT 1

Обновление NULL дат (не работает)

UPDATE my_table
SET date = DATE_ADD((SELECT date FROM my_table ORDER BY date DESC LIMIT 1), INTERVAL 1 DAY)
WHERE date IS NULL
ORDER BY id ASC

Как я могу это сделать? Или это невозможно?


person doitlikejustin    schedule 15.08.2013    source источник
comment
Вы хотите иметь одинаковую дату для всех идентификаторов с соответствующими датами, которые являются NULL, или вы хотите увеличивать дату от строки к строке?   -  person peterm    schedule 15.08.2013
comment
@peterm Увеличивайте дату от строки к строке.   -  person doitlikejustin    schedule 15.08.2013


Ответы (2)


Пытаться

UPDATE Table1 t1 JOIN
(
  SELECT id, @n := @n + 1 rnum
    FROM Table1 CROSS JOIN (SELECT @n := 0) i
   WHERE date IS NULL
   ORDER BY id
) t2 ON t1.id = t2.id CROSS JOIN
(
  SELECT MAX(date) date FROM Table1
) q
   SET t1.date = q.date + INTERVAL t2.rnum DAY

Результат:

|    ID |       DATE |
----------------------
| 10500 | 2013-08-18 |
| 10501 | 2013-08-16 |
| 10502 | 2013-08-17 |
| 10503 | 2013-08-19 |
| 10504 | 2013-08-20 | --  date has been assigned
| 10505 | 2013-08-21 | --  date has been assigned

Вот демонстрация SQLFiddle.

Объяснение: В подзапросе с псевдонимом t2 мы берем все строки, где дата имеет значение NULL, упорядочиваем их по id и присваиваем номера строк, начиная с 1. К сожалению, в MySql нет реализации функции ROW_NUMBER(), поэтому мы делаем это с помощью пользователя. переменная @n, которая увеличивается при выборе строк. Для инициализации этой переменной мы используем подзапрос с псевдонимом i. И используйте CROSS JOIN, чтобы сделать его доступным для нашего подзапроса t2. Затем мы используем тот же метод (CROSS JOIN), чтобы получить максимальную дату в таблице и сделать ее доступной для каждой строки в нашем JOIN. Когда у нас есть все это, мы просто добавляем номер строки, который представляет количество дней) добавляем его к максимальной дате и назначаем столбцу date в нашей таблице.

person peterm    schedule 15.08.2013
comment
Отлично. Похоже, это работает. Не могли бы вы немного объяснить запрос, чтобы я понял, что здесь происходит? - person doitlikejustin; 15.08.2013
comment
Спасибо. Есть ли причина, по которой вы не используете AS для псевдонимов? - person doitlikejustin; 15.08.2013
comment
Всегда пожалуйста. Я рад, что смог помочь :) Причина в том, что это просто короче и меньше беспорядка. - person peterm; 15.08.2013

Вместо этого используйте синтаксис join:

UPDATE my_table cross join
       (SELECT max(date) as maxdate FROM my_table) const
SET my_table.date = DATE_ADD(const.maxdate, INTERVAL 1 DAY)
WHERE my_table.date IS NULL;
person Gordon Linoff    schedule 15.08.2013
comment
Мне нравится идея, но это работает только на следующей записи, после этого она не увеличивается, и я получаю ошибку дублирующей записи, так как даты не могут быть одинаковыми. - person doitlikejustin; 15.08.2013