如何使用 SQL 更新语句为每个 TAG 记录值递增一个值
How do I increment a value using an SQL update statement for each TAG record value
我正在执行一个 SSIS ETL 过程,该过程将数据加载到 table 并使用执行 SQL 语句作为执行的最后一个组件,以根据内容列的值更新 TAG 值.一个例子是
update [payments].[MTFileValidationData_UAT]
set TAG = 'Header'
where left(content,3) = '{1:' and [TransactionId] = ?
这实际上是针对一系列不同的标签完成的。完成此操作后,有一个名为 FileSequenceNumber
的列需要用每个标签的编号进行更新,以便我最终可以将 UAT 和生产文件相互比较以进行测试。
我还需要更新列 FileSequenceNumber
以便为每个文件名的每个标签提供一个序列号。
预期结果:
RowID | TransactionId | FileName | FileType | Tag | Content | Location | FileSequenceNumber |
------+---------------+----------+----------+-----+---------+----------+--------------------+
1 9052312 ABCFile NULL Header XXX October 1
2 9052312 ABCFile NULL Header ZZZ October 2
3 9052312 ABCFile NULL Header YYY October 3
3 9052312 ABCFile NULL 32B YYY October 1
3 9052312 ABCFile NULL 32B YYY October 2
3 9052312 ABCFile NULL 32B YYY October 3
我相信您希望使用 SQL Server 2012+ 提供的精美 windowing 功能。具体来说,ROW_NUMBER
UPDATE
T
SET
FileSequenceNumber = ROW_NUMBER() OVER (PARTITION BY T.Tag ORDER BY RowID)
FROM
dbo.myTable AS T;
每次标记更改时,partition by
都会重置计数器
order by
指定应如何在标记列中生成序列。
如评论所述,window 函数只能出现在 select 或 oder by 子句中,因此我们必须修改以满足条件。用于工作重现的 DBFiddle https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=d731c14c9e15d70eb3b1d34f7b0f61a8
UPDATE
T
SET
T.FileSequenceNumber = TI.FileSequenceNumber
FROM
dbo.SO_61461648 AS T
INNER JOIN
(
SELECT
FileSequenceNumber = ROW_NUMBER() OVER (PARTITION BY TI.Tag ORDER BY TI.RowID)
, TI.RowID
FROM
dbo.SO_61461648 AS TI
) aS TI
ON TI.RowID = T.RowID;
如果提供的数据是准确的,并且有 4 行具有相同的 RowID,那么您需要采取严厉的方法并转储 table 并重新加载它。
-- Heavy handed approach to dump the table and reload with new value in case RowID is not unique
declare @Intermediary table
(
RowID int NOT NULL
, Tag varchar(30) NOT NULL
);
DELETE T
OUTPUT DELETED.RowID, DELETED.Tag
INTO @intermediary(RowID, Tag)
FROM
dbo.SO_61461648 AS T;
INSERT INTO
dbo.SO_61461648
SELECT
D.*
, ROW_NUMBER() OVER (PARTITION BY D.Tag ORDER BY D.RowID)
FROM @Intermediary AS D;
SELECT * FROM dbo.SO_61461648 AS T order by RowID, FileSequenceNumber;
我正在执行一个 SSIS ETL 过程,该过程将数据加载到 table 并使用执行 SQL 语句作为执行的最后一个组件,以根据内容列的值更新 TAG 值.一个例子是
update [payments].[MTFileValidationData_UAT]
set TAG = 'Header'
where left(content,3) = '{1:' and [TransactionId] = ?
这实际上是针对一系列不同的标签完成的。完成此操作后,有一个名为 FileSequenceNumber
的列需要用每个标签的编号进行更新,以便我最终可以将 UAT 和生产文件相互比较以进行测试。
我还需要更新列 FileSequenceNumber
以便为每个文件名的每个标签提供一个序列号。
预期结果:
RowID | TransactionId | FileName | FileType | Tag | Content | Location | FileSequenceNumber |
------+---------------+----------+----------+-----+---------+----------+--------------------+
1 9052312 ABCFile NULL Header XXX October 1
2 9052312 ABCFile NULL Header ZZZ October 2
3 9052312 ABCFile NULL Header YYY October 3
3 9052312 ABCFile NULL 32B YYY October 1
3 9052312 ABCFile NULL 32B YYY October 2
3 9052312 ABCFile NULL 32B YYY October 3
我相信您希望使用 SQL Server 2012+ 提供的精美 windowing 功能。具体来说,ROW_NUMBER
UPDATE
T
SET
FileSequenceNumber = ROW_NUMBER() OVER (PARTITION BY T.Tag ORDER BY RowID)
FROM
dbo.myTable AS T;
每次标记更改时,partition by
都会重置计数器
order by
指定应如何在标记列中生成序列。
如评论所述,window 函数只能出现在 select 或 oder by 子句中,因此我们必须修改以满足条件。用于工作重现的 DBFiddle https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=d731c14c9e15d70eb3b1d34f7b0f61a8
UPDATE
T
SET
T.FileSequenceNumber = TI.FileSequenceNumber
FROM
dbo.SO_61461648 AS T
INNER JOIN
(
SELECT
FileSequenceNumber = ROW_NUMBER() OVER (PARTITION BY TI.Tag ORDER BY TI.RowID)
, TI.RowID
FROM
dbo.SO_61461648 AS TI
) aS TI
ON TI.RowID = T.RowID;
如果提供的数据是准确的,并且有 4 行具有相同的 RowID,那么您需要采取严厉的方法并转储 table 并重新加载它。
-- Heavy handed approach to dump the table and reload with new value in case RowID is not unique
declare @Intermediary table
(
RowID int NOT NULL
, Tag varchar(30) NOT NULL
);
DELETE T
OUTPUT DELETED.RowID, DELETED.Tag
INTO @intermediary(RowID, Tag)
FROM
dbo.SO_61461648 AS T;
INSERT INTO
dbo.SO_61461648
SELECT
D.*
, ROW_NUMBER() OVER (PARTITION BY D.Tag ORDER BY D.RowID)
FROM @Intermediary AS D;
SELECT * FROM dbo.SO_61461648 AS T order by RowID, FileSequenceNumber;