I have this fairly straightforward table with ID, Position, Name columns.
ID Position Name
1 1 RecordX
2 3 RecordY
3 2 RecordZ
The Position column serves as an index for displaying the records in a user defined order, it should be unique, can not be lower than 1 and not be higher than the number of records in the table, in this case 3. The column doesn’t enforce uniqueness so temporarily there can be 2 records with the same Position, but eventually no two records should have the same position for the correct working of the program.
Currently, in order to swap the position of two records I need to do 3 queries, namely:
-
find the other record’s
ID -
update the current record’s
Positionto match the other record’sPosition -
update the other record’s
Positionby it’s previously foundID(Since momentarily there will be two records with the samePosition, updating byPositionis not possible.
I feel there should be a way to do this with less rounds to the database, and thus with less than 3 queries. How should I approach this problem?
Single “swap” operation…
SWAP(@old_pos, @new_pos)
This doesn’t easily expand to a table of swap-operations though. This is because it will try to do all the swaps at once, when in fact the swaps must happen in a specific order…
Also, if you want to do SWAP(@id, @new_pos) you need to either do a sub-query or self join on the table you are updating. MySQL doesn’t like that, and although there are ways around the limitation, it makes things get a bit messy…
(I think that will work)
NOTE:
Both of these assume that BOTH @old_pos and @new_pos, or @id and @new_pos are found, it doesn’t check, and will make a mess if they don’t exist.
This can be resolved by putting it in a transaction, and rolling back if ROW_COUNT() shows that only 1 record is updated.