2010-11-24 98 views
0

在我的Products表中,我有一個名爲'order'的列,其中包含用戶在CMS中通過下拉框設置的整數1,2,3等。SQL Server:更改DB中的訂單列

我希望能夠通過相應地傳遞舊訂單,新訂單和產品ID來重新排序數據庫中的所有行,當用戶更改某個產品的訂單時。

如:

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

如果採用改變沙發是2階,我需要根據這種變化重置所有其他產品。

優化不是一個巨大的問題,因爲不會有很多表中的項目。

這個任務最有效的邏輯是什麼?

感謝

+0

你的邏輯似乎並不完整。當用戶更改爲2時,適用於重置所有其他產品的邏輯是什麼?重置標準? – InSane 2010-11-24 08:05:03

+1

你寫*什麼是最有效的邏輯* - 但也*優化不是一個巨大的關注*。那麼,在這種情況下,*高效*意味着什麼? – 2010-11-24 08:08:01

回答

1

order列並不需要包含連續整數 - 可以有差距。唯一重要的是他們的相對順序。您可以從100,200,300 ...開始,而不是1,2,3,...使得更容易調整相對順序,而不必僅僅因爲要移動一個項目而更新數據庫中的所有項目。

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

偶爾您會發現在插入點處沒有空隙。然後你可以重新編號整個表格。

0

如何像這樣(僞代碼)

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

要做到這一點,你的表需要有一個唯一的標識符,要能夠

Couch 2 

區分
Pillow 2 

創建你的訂單表像這樣

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] 

填充一次,你有這樣的(注意我是如何把隨機的唯一idenitifiers的唯一密鑰ID):

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

你改變沙發的數量爲2:

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

我們可以使用ID來區分沙發和枕頭,兩者都有號碼2。該ROW_NUMBER()函數爲我們提供了所需的編號:

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

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

然後只需用這些新的數字更新,使用的問題WITH子句:

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  
    ) 

結果:

ID Item Number 
593 Chair 1 
117 Couch 2 
207 Pillow 3 
681 Bed  4 
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)