DB2更新列,根据另一列中的不同值递增数字

时间:2016-02-18 09:32:36

标签: sql sql-update db2

对于每个不同的ref_no值,我想使用从1开始递增值的运行序列来更新seq_no列。

REF_NO  SEQ_NO (initial)    SEQ_NO (expected)
------- -------             -------
   111.      -                   1.
   111.      -                   2.
   111.      -                   3.
   222.      -                   1.
   222.      -                   2.
   333.      -                   1.
   100.      -                   1.
   100.      -                   2.
   100.      -                   3.
   100.      -                   4.
     0.      -                   1.
   333.      -                   2.
   100.      -                   5.
   200.      -                   1.

我只能通过重复多个陈述来做到这一点:

declare x1 cursor for select * from xyz where seq_no is null for update of seq_no
open x1

fetch from x1
update xyz a set a.seq_no = (select nvl(max(b.seq_no)+1, 1) from xyz b where b.ref_no = a.ref_no) where current of x1
  -- REPEAT ABOVE TWO STATEMENTS UNTIL FETCH RETURNS NO ROW --

close x1
select * from xyz

是否可以使用单个UPDATE语句完全执行此操作只运行一次以更新整个表?该数据库是IBM DB2。

注意:不同ref_no的行的实际顺序是任意的,并不重要。

2 个答案:

答案 0 :(得分:3)

使用Row_Number窗口功能

select row_number()over(partition by REF_NO  order by REF_NO) as seq_no
from yourtable

要更新表格,请尝试此

MERGE INTO xyz A
USING (SELECT rowid row_id,
              Row_number()
                OVER(
                  partition BY ref_no
                  ORDER BY ref_no ) as seq_no
       FROM   xyz) B
ON A.rowid = B.row_id
WHEN MATCHED THEN
  UPDATE SET A.seq_no = B.seq_no 

答案 1 :(得分:2)

如果您没有表主键,可以使用Relative Record Number SQL Function和下面的查询来更新结果:

MERGE INTO
    ref AS r
USING
    (
        SELECT
            RRN(ref) AS rrn,
            ROW_NUMBER() OVER(PARTITION BY ref_no ORDER BY RRN(ref)) AS seq_no
        FROM
            ref
    ) AS n
ON
    RRN(r) = n.rrn
WHEN MATCHED THEN
    UPDATE SET
        seq_no = n.seq_no;

通常,在您的表上没有主键列是个坏主意。考虑添加标识列。它可以在已有的表格中完成:

ALTER TABLE ref ADD COLUMN id INTEGER NOT NULL DEFAULT 0;
ALTER TABLE ref ALTER COLUMN id SET GENERATED ALWAYS AS IDENTITY;