Let's say I have a Product
table in a shopping site's database to keep description, price, etc of store's products. What is the most efficient way to make my client able to re-order these products?
I create an Order
column (integer) to use for sorting records but that gives me some headaches regarding performance due to the primitive methods I use to change the order of every record after the one I actually need to change. An example:
Id Order 5 3 8 1 26 2 32 5 120 4
Now what can I do to change the order of the record with ID=26
to 3?
What I did was creating a procedure which checks whether there is a record in the target order (3) and updates the order of the row (ID=26) if not. If there is a record in target order the procedure executes itself sending that row's ID with target order + 1
as parameters.
That causes to update every single record after the one I want to change to make room:
Id Order 5 4 8 1 26 3 32 6 120 5
So what would a smarter person do?
Edit:
I need the order column of an item to be enough for sorting with no secondary keys involved. Order column alone must specify a unique place for its record.
In addition to all, I wonder if I can implement something like of a linked list: A 'Next' column instead of an 'Order' column to keep the next items ID. But I have no idea how to write the query that retrieves the records with correct order. If anyone has an idea about this approach as well, please share.
The ORDER BY statement in SQL is used to sort the fetched data in either ascending or descending according to one or more columns. By default ORDER BY sorts the data in ascending order. We can use the keyword DESC to sort the data in descending order and the keyword ASC to sort in ascending order.
To sort by a column: Type: SELECT columns FROM table ORDER BY sort_column [ASC | DESC]; columns is one or more comma-separated column names, sort_column is the name of the column on which to sort the result, and table is the name of the table that contains columns and sort_column.
After the ORDER BY keyword, add the name of the column by which you'd like to sort records first (in our example, salary). Then, after a comma, add the second column (in our example, last_name ). You can modify the sorting order (ascending or descending) separately for each column.
Update product set order = order+1 where order >= @value changed
Though over time you'll get larger and larger "spaces" in your order but it will still "sort"
This will add 1 to the value being changed and every value after it in one statement, but the above statement is still true. larger and larger "spaces" will form in your order possibly getting to the point of exceeding an INT value.
Alternate solution given desire for no spaces:
Imagine a procedure for: UpdateSortOrder with parameters of @NewOrderVal, @IDToChange,@OriginalOrderVal
Two step process depending if new/old order is moving up or down the sort.
If @NewOrderVal < @OriginalOrderVal --Moving down chain --Create space for the movement; no point in changing the original Update product set order = order+1 where order BETWEEN @NewOrderVal and @OriginalOrderVal-1; end if If @NewOrderVal > @OriginalOrderVal --Moving up chain --Create space for the momvement; no point in changing the original Update product set order = order-1 where order between @OriginalOrderVal+1 and @NewOrderVal end if --Finally update the one we moved to correct value update product set order = @newOrderVal where ID=@IDToChange;
Regarding best practice; most environments I've been in typically want something grouped by category and sorted alphabetically or based on "popularity on sale" thus negating the need to provide a user defined sort.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With