I am trying to

  1. get the latest date in a database, and
  2. based on that date update every record that has a NULL date, increasing the date by 1 day.

I can get the latest date by using the Latest Date query below. I need to do this first because the dates in the table are not in order. If need be, I can run this query, manually write it down, then run the UPDATE query based on this date. I would prefer to run everything without the manual process.

The last query I have at the bottom of the question is my test query for trying to update the dates, however I had no luck getting it to work.

Table (dates are not in order)

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

Selecting the latest date (starting point for UPDATE)

SELECT date
FROM my_table
ORDER BY date DESC
LIMIT 1

Updating NULL dates (doesn't work)

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

How can I accomplish this? Or is this not possible?

有帮助吗?

解决方案

Try

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

Result:

|    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

Here is SQLFiddle demo

Explanation: In a subquery with an alias t2 we grab all rows where date IS NULL order them by id and assign row numbers starting from 1. Unfortunately MySql doesn't have an implementation for ROW_NUMBER() function so we do it with a user variable @n which is incremented while rows are selected. To initialize this variable we use a subquery with an alias i. And use CROSS JOIN to make it available for our subquery t2. We then use the same technique (CROSS JOIN) to grab a max date in the table and make it available for every row in our JOIN. ONce we have all that we just add a line number, which represents a number of days) add it to the max date and assign to date column in our table.

其他提示

Use join syntax instead:

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;
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top