更新表列以填充缺少的序列号

时间:2016-01-18 11:04:21

标签: sql sql-server

我有一张包含以下数据的表

CategoryID   Name   Sequence
10           One    1
10           Two    2
10           Three  4
20           One    1
20           Two    3
20           Three  4
30           One    1
30           Two    2
30           Three  3

现在我想更新类别id 10和20的表,以便更正序列,最终结果如下。

CategoryID   Name   Sequence
    10           One    1
    10           Two    2
    10           Three  3
    20           One    1
    20           Two    2
    20           Three  3
    30           One    1
    30           Two    2
    30           Three  3

我正在尝试使用公用表表达式但无法执行此操作。知道如何完成这项任务吗?

我不想逐一更新每一行。我想创建一个通用的解决方案。因此,如果要更新的记录集很大,则可以使用相同的代码来代替复制粘贴和更改每行的值。

注意: 出于理解目的,名称列中的值是虚构的。它可以是任何东西。例如乔,美国等

4 个答案:

答案 0 :(得分:1)

很难保持序列号无间隙。你会有插入/更新/删除触发器来保证这一点。

然而,它并不是真的需要,因为你可以随时使用分析函数ROW_NUMBER获得无间隙行数:

select 
  categoryid, 
  name, 
  sequence, 
  row_number() over (partition by categoryid order by sequence)
from my table
order by categoryid, sequence;

答案 1 :(得分:1)

UPDATE t
SET Sequence = RN
FROM
(
    SELECT Sequence, ROW_NUMBER() OVER (PARTITION BY CategoryID ORDER BY CategoryID) 
    AS RN FROM Table_1
) t

对于特定类别ID

UPDATE t
SET Sequence = RN
FROM
(
    SELECT Sequence, ROW_NUMBER() OVER (PARTITION BY CategoryID ORDER BY CategoryID) AS RN 
    FROM Table_1 
    WHERE CategoryID = 10
) t

原始值

enter image description here

输出

enter image description here

答案 2 :(得分:0)

我不确定我是否理解正确,但你不能这样做:

Update table set sequence = 1 where Name = 'one';
Update table set sequence = 2 where Name = 'two';
Update table set sequence = 3 where Name = 'three';

或者我错过了什么?

答案 3 :(得分:0)

我提出了以下代码来创建通用解决方案。我做过单元测试。但是可能存在极端情况。它虽然为我做了工作。

IF OBJECT_ID('tempdb..#MY_TEMP_TABLE') IS NOT NULL
    DROP TABLE #MY_TEMP_TABLE

CREATE table #MY_TEMP_TABLE(
CategoryID INT,
[Custom_Index] INT)

DECLARE @Index INT = 0 --
DECLARE @TotalParams INT = 0 --
DECLARE @Name VARCHAR(100)

INSERT INTO #MY_TEMP_TABLE
SELECT CategoryID, RANK() OVER (ORDER BY [Sequence]) AS [Custom_Index] 
FROM MY_ACTUAL_TABLE
WHERE CategoryID =  20

WHILE @Index < @TotalParams
BEGIN
    SET @Index = @Index + 1

    SELECT @Name = [Name] 
    FROM #MY_TEMP_TABLE
    WHERE #MY_TEMP_TABLE.[Custom_Index] = @Index

    UPDATE 
    MY_ACTUAL_TABLE
    SET [Sequence] = @Index
    WHERE CategoryID = 20 AND [Name] = @Name

END
相关问题