Here’s an SQL statement (actually two statements) that works — it’s taking a series of matching rows and adding a delivery_number which increments for each row:
SELECT @i:=0;
UPDATE pipeline_deliveries AS d
SET d.delivery_number = @i:=@i+1
WHERE d.pipelineID = 11
ORDER BY d.setup_time;
But now, the client no longer wants them ordered by setup_time. They needed to be ordered according to departure time, which is a field in another table. I can’t figure out how to do this.
The MySQL docs, as well as this answer, suggest that in version 4.0 and up (we’re running MySQL 5.0) I should be able to do this:
SELECT @i:=0;
UPDATE pipeline_deliveries AS d RIGHT JOIN pipeline_routesXdeliveryID AS rXd
ON d.pipeline_deliveryID = rXd.pipeline_deliveryID
LEFT JOIN pipeline_routes AS r
ON rXd.pipeline_routeID = r.pipeline_routeID
SET d.delivery_number = @i:=@i+1
WHERE d.pipelineID = 11
ORDER BY r.departure_time,d.pipeline_deliveryID;
but I get the error #1221 - Incorrect usage of UPDATE and ORDER BY.
So what’s the correct usage?
You can’t mix
UPDATEjoining 2 (or more) tables andORDER BY.You can bypass the limitation, with something like this:
The above uses two features of MySQL, user defined variables and ordering inside a derived table. Because the latter is not standard SQL, it may very well break in a feature release of MySQL (when the optimizer is clever enough to figure out that ordering inside a derived table is useless unless there is a
LIMITclause). In fact the query would do exactly that in the latest versions of MariaDB (5.3 and 5.5). It would run as if theORDER BYwas not there and the results would not be the expected. See a related question at MariaDB site: GROUP BY trick has been optimized away.The same may very well happen in any future release of main-strean MySQL (maybe in 5.6, anyone care to test this?) that will improve the optimizer code.
So, it’s better to write this in standard SQL. The best would be window functions which haven’t been implemented yet. But you could also use a self-join, which will be not very bad regarding efficiency, as long as you are dealing with a small subset of rows to be affected by the update.