0

In my Products table I have a column called 'order' which contains integers 1, 2, 3 etc which are set by a drop down box by the user in the CMS.

I want to be able to re order all rows in the DB by passing the old order, new order and product ID accordingly when the user changes the order of a certain product.

Eg:

Chair - order 1
Pillow - order 2
Bed - order 3
Couch - order 4

If the use changes Couch to be order 2, I need to reset all other products according to this change.

Optimisation is not a huge concern as there wont be many items in the table.

What is the most efficient logic for this task?

Thanks

3
  • Your logic doesnt seem to be complete. When user changes couch to 2, what is the logic to apply to RESET all other products? Criteria for the reset? Commented Nov 24, 2010 at 8:05
  • 1
    You write What is the most efficient logic - but also Optimisation is not a huge concern. So what do you mean by efficient in this context? Commented Nov 24, 2010 at 8:08
  • 1
    What if 2 users reorder at the same time? Commented Nov 24, 2010 at 8:08

4 Answers 4

1

Your order column does not need to contain consecutive integers - there can be gaps. The only thing that is important is their relative order. You can start with 100, 200, 300, ... instead of 1, 2, 3, ... making it easier to adjust the relative ordering without having to update all items in the database just because you want to move one item.

100 foo ---      200 bar
200 bar    \     300 baz
300 baz     ---> 350 foo
400 qux          400 qux

Occasionally you will find that there are no gap left at the insertion point. Then you can renumber the entire table.

Sign up to request clarification or add additional context in comments.

1 Comment

I've used floats before, for the same reason - you can almost always find a value between the two you want to insert between.
1
CREATE PROCEDURE ChangeProductOrder(@productID int, @order int)
AS

DECLARE @oldOrder int
SET @oldOrder = (SELECT [Order] FROM dbo.Products WHERE productid = @productID)

UPDATE p
SET [order] = CASE WHEN ProductID = @productID 
                 THEN @order 
                 ELSE [Order] - SIGN(@order - @oldOrder) 
              END
FROM dbo.Products p
WHERE ([Order] BETWEEN @oldOrder AND @order
OR [Order] BETWEEN @order AND @oldOrder)

Comments

0

How about something like this (Pseudo code)

UPDATE Table
SET     Order = Order + 1
WHERe   Order >= NewOrderForCouch 
AND     Order < CurrentOrderForCouch;
UPDATE Table
SET     Order = NewOrderForCouch
WHERe   ID = CouchID;

Comments

0

To do this, your table needs to have a unique identifier, to be able to differentiate between

Couch 2

and

Pillow 2

Create your Orders table like this

CREATE TABLE [dbo].[Orders](
    [ID] [int] NOT NULL,
    [Item] [varchar](50) NOT NULL,
    [Number] [int] NOT NULL,
 CONSTRAINT [PK_Orders] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
) ON [PRIMARY]
) ON [PRIMARY]

Once populated, you have this (notice how I've put random unique idenitifiers in the unique key ID):

ID      Item    Number
593 Chair   1
207 Pillow  2
681 Bed     3
117 Couch   4

You change the number of Couch to 2:

ID      Item    Number
593 Chair   1
207 Pillow  2
681 Bed     3
117 Couch   2

We can use ID to differentiate Couch and Pillow that both have number 2. The ROW_NUMBER() function gives us the desired numbering:

SELECT
    id, Item, number, ROW_NUMBER() OVER(ORDER BY number)
FROM
    Orders

giving

593 Chair   1   1
117 Couch   2   2
207 Pillow  2   3
681 Bed     3   4

It's then just a matter of updating with these new numbers, using a WITH clause:

WITH NewOrders(newnum, id) AS (
    SELECT
        ROW_NUMBER() OVER(ORDER BY number), id
    FROM
        Orders
)
UPDATE
    Orders
SET
    number = (
        SELECT
            newnum
        FROM
            NewOrders
        WHERE
            neworders.id = orders.id    
    )

Results:

ID  Item    Number
593 Chair   1
117 Couch   2
207 Pillow  3
681 Bed     4

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.