Singola operazione di "scambio"...
SWAP(@vecchio_pos, @nuovo_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)
Tuttavia, questo non si espande facilmente in una tabella di operazioni di scambio. Questo perché proverà a fare tutti gli scambi contemporaneamente, quando in realtà gli scambi devono avvenire in un ordine specifico...
Inoltre, se vuoi eseguire SWAP(@id, @new_pos) devi eseguire una sottoquery o unirti automaticamente al tavolo che stai aggiornando. A MySQL non piace e, sebbene ci siano modi per aggirare la limitazione, rende le cose un po' confuse...
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
(Io penso funzionerà)
NOTA:
Entrambi presuppongono che ENTRAMBI @old_pos e @new_pos, o @id e @new_pos vengano trovati, non viene verificato e lo farà fare un pasticcio se non esistono.
Questo può essere risolto inserendolo in una transazione e ripristinando se ROW_COUNT() mostra che è stato aggiornato solo 1 record.