Jedna operace "swap"...
SWAP(@starý_pos, @nový_pos)
UPDATE
my_table
SET
position = CASE WHEN position = @old_pos THEN @new_pos ELSE @old_pos END
WHERE
position IN (@old_pos, @new_pos)
To však nelze snadno rozšířit na tabulku swapovacích operací. Je to proto, že se pokusí provést všechny swapy najednou, i když ve skutečnosti k výměnám musí dojít v určitém pořadí...
Také, pokud chcete provést SWAP(@id, @new_pos), musíte buď provést dílčí dotaz, nebo se sami připojit k tabulce, kterou aktualizujete. To se MySQL nelíbí, a i když existují způsoby, jak omezení obejít, věci se tím trochu zamotávají...
UPDATE
my_table
INNER JOIN
(SELECT position AS old_pos, @new_pos AS new_pos FROM (SELECT position FROM my_table WHERE id = @id)) AS params
ON my_table.position IN (params.old_pos, params.new_pos)
SET
myTable.position = CASE WHEN position = old_pos THEN new_pos ELSE old_pos END
(myslím to bude fungovat)
POZNÁMKA:
Oba předpokládají, že OBA @old_pos i @new_pos nebo @id a @new_pos jsou nalezeny, nekontroluje to a bude dělat nepořádek, pokud neexistují.
To lze vyřešit vložením do transakce a vrácením zpět, pokud ROW_COUNT() ukáže, že je aktualizován pouze 1 záznam.