我有一张包含以下数据的表
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
我正在尝试使用公用表表达式但无法执行此操作。知道如何完成这项任务吗?
我不想逐一更新每一行。我想创建一个通用的解决方案。因此,如果要更新的记录集很大,则可以使用相同的代码来代替复制粘贴和更改每行的值。
注意: 出于理解目的,名称列中的值是虚构的。它可以是任何东西。例如乔,美国等
答案 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
原始值
输出
答案 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