【问题标题】:How do I increment a value using an SQL update statement for each TAG record value如何使用 SQL 更新语句为每个 TAG 记录值增加值
【发布时间】:2020-04-27 14:51:21
【问题描述】:

我正在执行一个 SSIS ETL 流程,该流程将数据加载到表中,并使用执行 SQL 语句作为执行的最后一个组件,以根据 Content 列的值更新 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       

【问题讨论】:

  • 只需要更新当前更新的行吗?还是需要更新其他行?
  • @GordonLinoff 所有行都需要更新。标记数据是从更新语句中作为一个整体填充的。与 FileSequenceNumber 相同。所有行都需要由更新语句填充。
  • 这里有两个问题,是吗? 1) 如何为各种内容值填充 TAG。 2)如何回填FileSequenceNumber。也许您的问题可以通过显示表 A) 发布数据流(初始状态)的状态来改进。 B)发布标签回填 C)发布文件序列号填充
  • 不,这只是一个问题。我正在成功填充标签数据。我需要的是每个文件名每个标签的序列号。
  • @billinkc 这只是一个问题。标签数据已成功填充。我只是想展示一个如何填充它的示例,以便我可以尝试以相同的方式填充标签数据。我只需要每个文件名的每个标签的序列号。就是这样。

标签: sql sql-server ssis


【解决方案1】:

我相信您希望使用 SQL Server 2012+ 提供的精美窗口功能。具体来说,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 指定如何在标签列中生成序列。

正如评论中所指出的,窗口函数只能出现在 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,那么您需要采取严厉的方法并转储表并重新加载它。

-- 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;

【讨论】:

  • 这可能行得通,我的问题是,在设置完所有数据后,我是否只在最后运行一次?谢谢。
  • 当我尝试运行它时,我得到“窗口函数只能出现在 SELECT 或 ORDER BY 子句中)
  • Fiddle 已被篡改
  • 我明白了,Blinkc 我只想再次感谢您的帮助。效果很好。
猜你喜欢
  • 1970-01-01
  • 2015-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-18
  • 1970-01-01
  • 2014-11-15
  • 1970-01-01
相关资源
最近更新 更多