【发布时间】:2020-06-11 21:28:01
【问题描述】:
我一直在寻找在单个 UPDATE 语句中执行此操作的方法,但没有成功。
这是我正在使用的数据集的示例:
+-------------------------+----------+--------------+----+--------+
| TIMESTAMP | USERNAME | VALUE | ID | IsDupe |
+-------------------------+----------+--------------+----+--------+
| 2020-02-12 07:00:03.000 | LINA | ORDER1 | 1 | 0 |
| 2020-02-12 07:00:03.000 | LINA | ITEM1 | 2 | 0 |
| 2020-02-12 07:09:09.000 | LINA | FINISH BUILD | 3 | 0 |
| 2020-02-12 07:09:10.000 | LINA | ORDER1 | 4 | 0 |
| 2020-02-12 07:09:11.000 | LINA | ITEM2 | 5 | 0 |
| 2020-02-12 07:24:07.000 | LINA | FINISH BUILD | 6 | 0 |
| 2020-02-12 07:24:08.000 | NAGA | ORDER2 | 7 | 0 |
| 2020-02-12 07:24:10.000 | NAGA | ITEM3 | 8 | 0 |
| 2020-02-12 07:45:06.000 | NAGA | FINISH BUILD | 9 | 0 |
| 2020-02-12 07:45:12.000 | NAGA | FINISH BUILD | 10 | 1 |
| 2020-02-12 07:45:13.000 | XELLOS | ORDER3 | 11 | 0 |
| 2020-02-12 07:45:14.000 | XELLOS | ITEM4 | 12 | 0 |
| 2020-02-12 07:56:36.000 | XELLOS | FINISH BUILD | 13 | 0 |
| 2020-02-12 07:56:39.000 | GOURRY | ORDER4 | 14 | 0 |
| 2020-02-12 07:56:40.000 | GOURRY | ITEM5 | 15 | 0 |
| 2020-02-12 08:30:11.000 | GOURRY | FINISH BUILD | 17 | 0 |
+-------------------------+----------+--------------+----+--------+
我想做的是创建一个额外的列作为迭代器,将这些行中的每一行分成三组,如下所示:
+-------------------------+----------+--------------+-------+--------+-------+
| TIMESTAMP | USERNAME | VALUE | IDCol | IsDupe | SetID |
+-------------------------+----------+--------------+-------+--------+-------+
| 2020-02-12 07:00:03.000 | LINA | ORDER1 | 1 | 0 | 1 |
| 2020-02-12 07:00:03.000 | LINA | ITEM1 | 2 | 0 | 1 |
| 2020-02-12 07:09:09.000 | LINA | FINISH BUILD | 3 | 0 | 1 |
| 2020-02-12 07:09:10.000 | LINA | ORDER1 | 4 | 0 | 2 |
| 2020-02-12 07:09:11.000 | LINA | ITEM2 | 5 | 0 | 2 |
| 2020-02-12 07:24:07.000 | LINA | FINISH BUILD | 6 | 0 | 2 |
| 2020-02-12 07:24:08.000 | NAGA | ORDER2 | 7 | 0 | 3 |
| 2020-02-12 07:24:10.000 | NAGA | ITEM3 | 8 | 0 | 3 |
| 2020-02-12 07:45:06.000 | NAGA | FINISH BUILD | 9 | 0 | 3 |
| 2020-02-12 07:45:12.000 | NAGA | FINISH BUILD | 10 | 1 | NULL |
| 2020-02-12 07:45:13.000 | XELLOS | ORDER3 | 11 | 0 | 4 |
| 2020-02-12 07:45:14.000 | XELLOS | ITEM4 | 12 | 0 | 4 |
| 2020-02-12 07:56:36.000 | XELLOS | FINISH BUILD | 13 | 0 | 4 |
| 2020-02-12 07:56:39.000 | GOURRY | ORDER4 | 14 | 0 | 5 |
| 2020-02-12 07:56:40.000 | GOURRY | ITEM5 | 15 | 0 | 5 |
| 2020-02-12 08:30:11.000 | GOURRY | FINISH BUILD | 17 | 0 | 5 |
+-------------------------+----------+--------------+-------+--------+-------+
我曾尝试在 SQL 中查找迭代语句,但对性能存在很大的担忧,因为这将是一组相对较大的数据,并且该语句需要在白天运行,从而影响生产。
另请注意,数据集中可能存在重复或其他错误。 IsDupe 设置为 1 的行必须从此语句中忽略。
我一直在尝试构建一个游标来执行此操作,但遇到了许多语法问题以及编写游标的一般经验不足:
DECLARE @MyCursor CURSOR;
DECLARE @SetID INT;
DECLARE @OUTPUTNUM TINYINT;
DECLARE @COUNTER TINYINT;
BEGIN
SET @MyCursor = CURSOR LOCAL FAST_FORWARD FOR
SELECT IsDupe from dbo.MyDataTable
WHERE IsDupe != 1
OPEN @MyCursor
FETCH NEXT FROM @MyCursor INTO @SetID
WHILE @@FETCH_STATUS = 0 BEGIN
SET @COUNTER = 0;
SET @OUTPUTNUM = 1;
WHILE @COUNTER < 3
BEGIN
UPDATE dbo.MyDataTable SET dbo.MyDataTable.SetID = @OUTPUTNUM
SET @COUNTER = @COUNTER + 1
END
SET @COUNTER = 0;
SET @OUTPUTNUM = @OUTPUTNUM + 1
FETCH NEXT FROM @MyCursor
INTO @SetID
END;
CLOSE @MyCursor ;
DEALLOCATE @MyCursor;
END;
当我运行它时,我收到以下消息:
[2:07:54 PM] Started executing query at Line 1
Commands completed successfully.
Total execution time: 00:00:00.026
但是没有结果,SetID 列的值还是全部为空。
【问题讨论】:
-
幸运的是您的光标不工作。游标在这里的工作是错误的工具。您的代码不起作用的原因是您的更新语句没有 where 子句,因此它一遍又一遍地更新整个表。我在这里看到的最大问题是您没有任何类型的密钥。无法知道第 1 行和第 2 行属于同一组。
-
用windows功能就可以完成,可以看下面我的回答
-
@Sean Lange 感谢您的评论。不幸的是,这张表中没有键,只是一堆乱七八糟的数据。我的任务是为这些数据添加一些结构,并试图找出一种方法来根据数据应该遵循的模式构建一个临时的键集:ORDER -> ITEM->FINISH BUILD。
标签: sql-server tsql while-loop sql-update database-cursor