我正在使用以下列的表格。
RouteID | StopID | DisplayOrder
1 1 1
2 2 1
1 3 2
2 4 1
现在由于某种原因,我的DisplayOrder会重复。我想运行脚本,找出重复的DisplayOrder记录,并使用下一个唯一值更改它们。
我无法将DisplayOrder字段设置为具有唯一约束,因为对于不同的Route,stop的Display order列将具有相同的值。
任何人都可以为我提供脚本或最佳方法来识别所有路径的Duplicate DisplayOrders,并使用该路线的下一个唯一displayOrders更新这些重复值。
答案 0 :(得分:1)
您没有发布正在运行的SQL Server版本,但假设您有权访问ROW_NUMBER()函数,您应该能够执行以下操作:请注意,这将更新所有内容,而不仅仅是那些重复的。如果这是一个问题,请告诉我。
编辑:
我稍微调整了脚本以调整您不希望影响现有显示顺序的愿望,但它仍然会为每一行设置一个新的DisplayOrder值。看看下面我的INSERT列表中的StopID#5 - 我将它设置为大于RouteID#2的先前值,但它只有一个更高。如果我完全按照您的意愿行事,并将DisplayOrder增加为StopID#2或#4,那么我基本上会创建一个新副本,因为现在StopID#4和StopID#5共享相同的DisplayOrder为2。
我正在做的是使用新的显示顺序值更新每条记录。 ORDER BY
函数中的ROW_NUMBER()
子句保留了原始的DisplayOrder,因此不会发生功能变化 - 但添加StopID将有助于确保始终如一地为其分配唯一值每一行。
-- Testing Data
DECLARE @StackOverflow TABLE (RouteID INT, StopID INT, DisplayOrder INT)
INSERT INTO @StackOverflow (RouteID, StopID, DisplayOrder) VALUES (1,1,1)
INSERT INTO @StackOverflow (RouteID, StopID, DisplayOrder) VALUES (2,2,1)
INSERT INTO @StackOverflow (RouteID, StopID, DisplayOrder) VALUES (1,3,2)
INSERT INTO @StackOverflow (RouteID, StopID, DisplayOrder) VALUES (2,4,1)
INSERT INTO @StackOverflow (RouteID, StopID, DisplayOrder) VALUES (2,5,2) -- this value is greater than a duplicated increment
-- Contains duplicated display order
SELECT * FROM @StackOverflow ORDER BY RouteID, DisplayOrder, StopID
-- overwrite ALL display orders with a sequential display order, assuming that StopID is the correct sequence
UPDATE @StackOverflow
SET DisplayOrder = s.RowNum
FROM
@StackOverflow so
INNER JOIN
(
SELECT
StopID,
ROW_NUMBER() OVER
(PARTITION BY RouteID
ORDER BY
DisplayOrder, -- adding this will preserve the existing display order
StopID -- this will rank the duplicates.
) RowNum
FROM @StackOverflow
) s ON
so.StopID = s.StopID
-- view final results
SELECT * FROM @StackOverflow ORDER BY RouteID, DisplayOrder, StopID