There’s a table like this one
______________________ | id | title | order | |----------------------| | 1 | test1 | 1 | |-----|--------|-------| | 2 | test2 | 2 | |-----|--------|-------| | 3 | test3 | 3 | |-----|--------|-------| | 4 | test4 | 4 | '----------------------'
when i introduce in my mysql shell a single update to a row
$sql> UPDATE `table` SET order=1 WHERE id=3;
And then procedure or method resamples order column in the before update lower values to get its order renewed like this
______________________ | id | title | order | |----------------------| | 1 | test1 | 2 | |-----|--------|-------| | 2 | test2 | 3 | |-----|--------|-------| | 3 | test3 | 1 | |-----|--------|-------| | 4 | test4 | 4 | '----------------------'
Any help would be appreciated, thanks!
There are two cases to consider, I think:
It is non-trivial either way. It is not clear whether there is a unique constraint on the column ‘order’; the end result is certainly supposed to have a unique ordering.
Notation:
In the example (illustrative of case 1):
As an alternative, consider moving id = 2 so it has order = 4:
You are basically adding or subtracting one from the ‘other’ rows, where those are the rows in the old order between the old position of the moved row and the new position of the moved row. In a pseudo-code, using $old and $new to identify the before and after positions of the moved row, and dealing with case 1 ($old > $new):
The corresponding code for case 2 ($old < $new) is:
Given the WHERE clause on the UPDATE as a whole, you may be able to remove the second WHEN in the CASE and replace it with a simple ELSE.
I think a stored procedure is in order – choosing between the two statements based on the input parameters $old, $new. You might be able to do something with a judicious mix of expressions such as ‘
($old - $new) / ABS($old - $new)‘ and ‘MIN($old, $new)‘ and ‘MAX($old, $new)‘ where the MIN/MAX are not aggregates but comparator functions for a pair of values (as found in Fortran, amongst other programming languages).Note that I am assuming that while a single SQL statement is executing, the uniqueness constraint (if any) is not enforced as each row is changed – only when the statement completes. This is necessary since you can’t actually control the order in which the rows are processed. I know of DBMS where this would cause trouble; I know of others where it would not.
It can all be done in a single SQL statement – but you do want a stored procedure to sort out the parameters to the statement. I use IBM Informix Dynamic Server (11.50.FC6 on MacOS X 10.6.2), and that is one of the DBMS that enforces the unique constraint on the ‘order’ column at the end of the statement. I did the development of the SQL without the UNIQUE constraint; that worked too, of course. (And yes, IDS does allow you to roll back DDL statements like CREATE TABLE and CREATE PROCEDURE. What did you say? Your DBMS doesn’t? How quaint!)
The pairs of invocations of the stored procedure with the numbers reversed reinstated the original order each time. Clearly, I could redefine the
v_incvariable so that instead of being just ±1, it was ‘LET v_inc = v_inc - v_min + v_gap;‘ and then the MOD expression would be just ‘MOD(order + v_inc, v_gap)‘. I’ve not checked whether this works with negative numbers.Adaptation to MySQL or other DBMS is left as an exercise for the reader.