在我的Products表中,我有一个名为'order'的列,其中包含整数1,2,3等,这些列由用户在CMS中的下拉框设置。
我希望能够通过在用户更改某个产品的订单时相应地传递旧订单,新订单和产品ID来重新订购数据库中的所有行。
例如:
Chair - order 1
Pillow - order 2
Bed - order 3
Couch - order 4
如果使用将Couch更改为订单2,我需要根据此更改重置所有其他产品。
优化不是一个大问题,因为表中没有很多项目。
此任务的最有效逻辑是什么?
由于
答案 0 :(得分:1)
您的order
列不需要包含连续的整数 - 可能存在间隙。唯一重要的是他们的相对秩序。您可以从100,200,300 ......开始,而不是1,2,3 ......,这样可以更轻松地调整相对排序,而无需仅仅因为要移动一个项目而更新数据库中的所有项目。
100 foo --- 200 bar 200 bar \ 300 baz 300 baz ---> 350 foo 400 qux 400 qux
偶尔您会发现插入点没有留下间隙。然后你可以重新编号整个表格。
答案 1 :(得分: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)
答案 2 :(得分:0)
这样的事情(伪代码)
UPDATE Table
SET Order = Order + 1
WHERe Order >= NewOrderForCouch
AND Order < CurrentOrderForCouch;
UPDATE Table
SET Order = NewOrderForCouch
WHERe ID = CouchID;
答案 3 :(得分: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]
一旦填充,你就有了这个(请注意我如何将随机唯一标识符放在唯一的密钥ID中):
ID Item Number
593 Chair 1
207 Pillow 2
681 Bed 3
117 Couch 4
您将Couch的数量更改为2:
ID Item Number
593 Chair 1
207 Pillow 2
681 Bed 3
117 Couch 2
我们可以使用ID来区分Couch和Pillow,它们都有数字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