Update multiple rows with different values in a single SQL query
There's a couple of ways to accomplish this decently efficiently.
If possible, you can do some sort of bulk insert to a temporary table. This depends somewhat on your RDBMS/host language, but at worst this can be accomplished with a simple dynamic SQL (using a
VALUES() clause), and then a standard update-from-another-table. Most systems provide utilities for bulk load, though
And this is somewhat RDBMS dependent as well, you could construct a dynamic update statement. In this case, where the
VALUES(...) clause inside the CTE has been created on-the-fly:
WITH Tmp(id, px, py) AS (VALUES(id1, newsPosX1, newPosY1), (id2, newsPosX2, newPosY2), ......................... , (idN, newsPosXN, newPosYN)) UPDATE TableToUpdate SET posX = (SELECT px FROM Tmp WHERE TableToUpdate.id = Tmp.id), posY = (SELECT py FROM Tmp WHERE TableToUpdate.id = Tmp.id) WHERE id IN (SELECT id FROM Tmp)
(According to the documentation, this should be valid SQLite syntax, but I can't get it to work in a fiddle)
Yes, you can do this, but I doubt that it would improve performances, unless your query has a real large latency.
You could do:
UPDATE table SET posX=CASE WHEN id=id THEN posX WHEN id=id THEN posX ... ELSE posX END, posY = CASE ... END WHERE id IN (id, id, id...);
The total cost is given more or less by: NUM_QUERIES * ( COST_QUERY_SETUP + COST_QUERY_PERFORMANCE ). This way, you knock down a bit on NUM_QUERIES, but COST_QUERY_PERFORMANCE goes up bigtime. If COST_QUERY_SETUP is really huge (e.g., you're calling some network service which is real slow) then, yes, you might still end up on top.
Otherwise, I'd try with indexing on id, or modifying the architecture.
In MySQL I think you could do this more easily with a multiple INSERT ON DUPLICATE KEY UPDATE (but am not sure, never tried).
Something like this might work for you:
"UPDATE myTable SET ... ; UPDATE myTable SET ... ; UPDATE myTable SET ... ; UPDATE myTable SET ... ;"
If any of the posX or posY values are the same, then they could be combined into one query
UPDATE myTable SET posX='39' WHERE id IN('2','3','40');