Locking

MS SQL Server - 將行值更新到具有行 ID 的下一行

  • February 20, 2012

我有一個如下表:

Newid1       a   b   c
  1       null  40  50
  2       null  45  55
  3       null  46  56
  4       null  47  57
  5       null  48  58

現在我想通過更新C列值來更新列中的值(例如:50到第二行,55到第三行,56到第四行……)。如何使用 WHILE 命令執行此操作。提前謝謝大家。

它可以在一個基於集合的操作中完成

使用 WHILE 可能會在您一遍又一遍地更新行時呼叫“萬聖節問題”。

使用 LAG 的 SQL Server 2012 更容易

DECLARE @t TABLE
(
   Newid1 int
   , a int  NULL
   , b int
   , c int
);

INSERT INTO @t VALUES(1, NULL, 40, 50)
       ,(2, NULL, 45, 55) ,(3, NULL, 46, 56)
       ,(4, NULL, 47, 57) ,(5, NULL, 48, 58);

-- SQL Server 2012
WITH t AS
(
   SELECT a, LAG(c) OVER (ORDER BY Newid1) AS nextC
   FROM @t
)
UPDATE t SET a = nextC;

SELECT * FROm @t;

但對於 SQL Server 2005+

DECLARE @t TABLE
(
   Newid1 int
   , a int  NULL
   , b int
   , c int
);

-- SQL Server 2005+
WITH t AS
(
   SELECT Newid1, ROW_NUMBER() OVER (ORDER BY Newid1) +1 AS nextID, a, c
   FROM @t
)
UPDATE t1
SET a = t2.c
FROM
  t AS t1
  JOIN
  t AS t2 ON t1.Newid1 = t2.nextID;

SELECT * FROM @t;

抱歉,不WHILE,如果您使用的是 SQL Server 2005 或更高版本,只需將 ROW_NUMBER 移到 1

DECLARE @t TABLE
(
   Newid1 int
   , a int  NULL
   , b int
   , c int
);

INSERT INTO @t VALUES(1, NULL, 40, 50)
INSERT INTO @t VALUES(2, NULL, 45, 55)
INSERT INTO @t VALUES(3, NULL, 46, 56)
INSERT INTO @t VALUES(4, NULL, 47, 57)
INSERT INTO @t VALUES(5, NULL, 48, 58)


UPDATE t
  SET a = c.c
FROM @t t
INNER JOIN 
(
   SELECT
    a.NewId1
    ,b.c
   FROM ( SELECT id = ROW_NUMBER ( ) OVER (ORDER BY Newid1) + 1, * FROM @t) b    
       LEFT JOIN ( SELECT id = ROW_NUMBER ( ) OVER (ORDER BY Newid1), * FROM @t) a
           ON a.Id = b.Id
) c
ON c.NewId1 = t.NewId1

SELECT  * FROM @t

引用自:https://dba.stackexchange.com/questions/13444