T-SQL脚本用于查找重复的DisplayOrder并分配唯一的DisplayOrder

时间:2014-08-20 09:46:07

标签: sql sql-server tsql

我正在使用以下列的表格。

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更新这些重复值。

1 个答案:

答案 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