为了帮助理解我有一个这样的表:
itemcode itemname icode serialnum
1 A 10 0
2 B 10 0
3 C 10 0
4 D 11 0
5 E 13 0
6 F 20 0
7 G 20 0
我希望在循环游标的帮助下使用单个更新查询使结果看起来像下表:
itemcode itemname icode serialnum
1 A 10 1
2 B 10 2
3 C 10 3
4 D 11 1
5 E 13 1
6 F 20 1
7 G 20 2
项目代码是此表中的主键。生成序列号背后的逻辑是每当icode更改时序列号重置为1.如果有人可以帮助解决方案,我需要单个更新查询来在游标的帮助下更新表吗?
答案 0 :(得分:3)
MS SQL Server 2008架构设置:
create table Item
(
itemcode int,
itemname char(1),
icode int,
serialnum int
)
insert into Item values
(1, 'A', 10, 0),
(2, 'B', 20, 0),
(3, 'C', 11, 0),
(4, 'D', 10, 0),
(5, 'E', 20, 0),
(6, 'F', 10, 0),
(7, 'G', 13, 0)
查询1 :
update I
set serialnum = rn
from
(
select serialnum,
row_number() over(partition by icode order by itemcode) as rn
from Item
) I
select *
from Item
<强> Results 强>:
| ITEMCODE | ITEMNAME | ICODE | SERIALNUM |
-------------------------------------------
| 1 | A | 10 | 1 |
| 2 | B | 20 | 1 |
| 3 | C | 11 | 1 |
| 4 | D | 10 | 2 |
| 5 | E | 20 | 2 |
| 6 | F | 10 | 3 |
| 7 | G | 13 | 1 |
<强> 强>
使用游标而不是使用游标的版本。
declare @itemcode int
declare @rn int
declare ItemCursor cursor local static forward_only read_only for
select itemcode,
row_number() over(partition by icode order by itemcode) as rn
from Item
open ItemCursor
fetch next from ItemCursor
into @itemcode, @rn
while @@fetch_status = 0
begin
update Item
set serialnum = @rn
where itemcode = @itemcode
fetch next from ItemCursor
into @itemcode, @rn
end
close ItemCursor
deallocate ItemCursor
答案 1 :(得分:3)
因此,您需要每个icode组的序列号。然后,您可以将ROW_NUMBER
与PARTITION BY icode
:
WITH CTE AS
(
SELECT itemcode, itemname, icode, serialnum,
, ROW_NUMBER() OVER (PARTITION BY icode ORDER BY itemcode) AS RN
FROM dbo.TableName
)
UPDATE CTE SET serialnum = RN;
如果您希望在每次更新时重新计算它,您可以使用触发器:
CREATE TRIGGER dbo.TableName_Updated
ON dbo.TableName
FOR UPDATE /* Fire this trigger when one or multiple rows are UPDATEd */
AS BEGIN
WITH CTE AS
(
SELECT itemcode, itemname, icode, serialnum,
, ROW_NUMBER() OVER (PARTITION BY icode ORDER BY itemcode) AS RN
FROM dbo.TableName t INNER JOIN INSERTED i
ON t.itemcode = i.itemcode
)
UPDATE CTE SET serialnum = RN
END