Thao tác "hoán đổi" duy nhất ...
SWAP (@old_pos, @new_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)
Tuy nhiên, điều này không dễ dàng mở rộng thành một bảng các hoạt động hoán đổi. Điều này là do nó sẽ cố gắng thực hiện tất cả các hoán đổi cùng một lúc, trong khi trên thực tế, các hoán đổi phải diễn ra theo một thứ tự cụ thể ...
Ngoài ra, nếu bạn muốn thực hiện SWAP (@id, @new_pos), bạn cần thực hiện một truy vấn phụ hoặc tự tham gia trên bảng bạn đang cập nhật. MySQL không thích điều đó, và mặc dù có những cách khắc phục hạn chế, nhưng nó khiến mọi thứ trở nên lộn xộn một chút ...
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
(Tôi nghĩ rằng điều đó sẽ hoạt động)
LƯU Ý:
Cả hai điều này đều giả định rằng CẢ @old_pos và @new_pos hoặc @id và @new_pos được tìm thấy, nó không kiểm tra và sẽ tạo ra một mớ hỗn độn nếu chúng không tồn tại.
Điều này có thể được giải quyết bằng cách đưa nó vào một giao dịch và quay trở lại nếu ROW_COUNT () cho thấy rằng chỉ có 1 bản ghi được cập nhật.