6

同胞查询作家,

我有一张如下表:

myTable t1
col2 col3
 2    1
 3    0
 4    0
 5    0
 6    0

我想用前一行中 col3 的值加上当前行中 col2 的值来更新 col3 上的每个零。所以我的桌子会像下面这样:

myTable t1
col2 col3
 2    1 
 3    4  (1+3)
 4    8  (4+4)
 5    13 (5+8) 
 6    19 (6+13)

我错过了这里的逻辑,也许是短视。我用光标尝试如下:

DECLARE @var3 FLOAT

DECLARE cursor3 CURSOR FOR
SELECT col2, col3 FROM table1
FOR UPDATE OF col3
OPEN cursor3


FETCH FIRST FROM cursor3
WHILE (@@FETCH_STATUS > -1)
BEGIN
 UPDATE @table1
 SET col3 = isnull(@var3, 0) + isnull(col2, 0)
 WHERE CURRENT OF cursor3
 FETCH NEXT FROM cursor3 INTO @var3
END

但这是错误的。有任何想法吗?

提前致谢。

4

4 回答 4

10

好的,试试这个。

CREATE TABLE MyTable (Id INT Identity, Col2 int, Col3 int)

INSERT INTO MyTable (Col2, Col3)
VALUES (2,1), (3,0), (4,0),(5,0),(6,0)

SELECT * from MyTable

WHILE (SELECT COUNT(*) FROM MyTable WHERE Col3=0) > 0
BEGIN
    UPDATE TOP (1) MyTable
    SET CoL3 = (Mytable.col2 + (select col3 from mytable t2 where (t2.id = mytable.id-1)))
    WHERE Col3 = 0
END

SELECT * from MyTable

使用WHILE在大多数情况下应该比游标更快的循环。

于 2010-11-03T17:48:39.190 回答
2

我在表中添加了一个标识列,最后使用了如下代码:

DECLARE @saldo_Q_previous FLOAT
DECLARE @ID INTEGER

DECLARE cursor3 CURSOR FOR
SELECT ID FROM @myTable
FOR UPDATE OF col2
OPEN cursor3

FETCH NEXT FROM cursor3 INTO @ID
FETCH NEXT FROM cursor3 INTO @ID

WHILE (@@FETCH_STATUS > -1)
BEGIN

    SET @col2_previous = ISNULL((SELECT TOP 1 col2 FROM @myTable WHERE ID < @ID ORDER BY ID DESC), 0)
    SET @vrQ = ISNULL((SELECT TOP 1 vr_Q FROM @myTable WHERE ID < @ID ORDER BY ID DESC), 0)

    UPDATE @myTable
    SET col2 = isnull(@col2_previous, 0) + isnull(vrMov_Q, 0)
    WHERE CURRENT OF cursor3

    FETCH NEXT FROM cursor3 INTO @ID
END

CLOSE cursor3
DEALLOCATE cursor3

它解决了我的问题。谢谢你们。

于 2010-11-17T13:03:30.647 回答
0

这是使用公用表表达式 (CTE) 更新数据的单个 UPDATE 语句。

WITH myTable2 AS
    (
    SELECT col2, col3, ROW_NUMBER() OVER (ORDER BY col2) AS sequence
    FROM myTable
    ),
  newTable AS
    (
    SELECT t1.col2, SUM(t2.col2) - SUM(t2.col3) AS col3
    FROM myTable2 t1
    LEFT OUTER JOIN myTable2 t2 ON t1.sequence >= t2.sequence
    GROUP BY t1.col2
    )

UPDATE myTable
SET col3 = newTable.col3
FROM myTable
JOIN newTable on myTable.col2 = newTable.col2
;
于 2010-11-03T18:20:56.993 回答
0

FWIW 使用 CURSOR 的主要、令人信服的理由是,如果不这样做,会对您的 rdbms 造成太大影响。您几乎总是可以使用 WHILE 循环而不是 CURSOR;一次处理一个记录;无论出于何种原因,您可能需要迭代大量记录时,这可能非常有用...... CURSOR 操作比等效的 SET 操作效率更高。

所以总的来说,它归结为速度和开销与效率......

游标几乎是最慢的方法,但开销最少,即使在 MSSQL 2012 中仍然有用......

于 2013-09-17T19:33:58.840 回答