使用“增量”列进行更新

时间:2018-05-12 04:11:17

标签: sql db2

示例表:

Sample
------
id (primary key)
secondaryId (optional secondary key)
crtdate (created date)
... (other fields)
  • 有些用户使用secondaryId来识别行(例如 应该是唯一的)
  • 创建行时,secondaryId未获取值,默认为0

  • 随后,行使用了secondaryId值。

  • 我需要将值0的所有行更新为下一个可用的数字。

期望的结果(带简化值):

   From:               To:

id secondaryId     id secondaryId
 1    0             1    7  // this is the max(secondaryId)+1
 2    0             2    8  // incrementing as we fill in the zeroes
 3    5             3    5  // already assigned
 4    0             4    9  // keep incrementing...
 5    6             5    6  // already assigned

此查询将完成我想要做的事情;但是,不支持CTE + UPDATE:

with temp(primary, rownumber) as ( 
     values (
         select 
             id,
             row_number() over (partition by secondaryId order by crtdate)+6 --6 is max secondaryId
         from Sample
         where secondaryId='0'
     )
update Sample set secondaryId=temp.rownumber where Sample.id=temp.id

有没有人建议采用不同的方法来解决这个问题?我现在正在遭受隧道视觉......

3 个答案:

答案 0 :(得分:3)

您可以使用 MERGE 语句,因为ID是主键,不会有任何重复项。

MERGE INTO Sample as trgt
Using (
select id, 
       row_number() over (partition by secondaryId order by crtdate)+6  secondaryId
          --6 is max secondaryId
       from Sample where secondaryId='0'
     ) as src
ON( src.id= trgt.id)
WHEN MATCHED THEN UPDATE SET trgt.secondaryid = src.secondaryId

答案 1 :(得分:1)

对于Template方法(不必知道最大值),您可以尝试:

create table tmptable as (
    select f1.id, row_number() over(order by f1.crtdate) + ifnull((select max(f2.secondaryId) from Sample f2), 0) newsecondary
    from Sample f1 where f1.secondaryId='0'
) with data;

update Sample f1
set f1.secondaryId=(
                    select f2.newsecondary
                    from tmptable f2
                    where f2.id=f1.id
                   )
where exists 
(
    select * from tmptable f2
    where f2.id=f1.id

);

drop table tmptable;

答案 2 :(得分:1)

你也可以UPDATE一个SELECT(以及“全选”),这可能是这里最好的解决方案

create table sample (
    id int not null primary key
,   secondaryId int not null
,   crtdate date not null
)
;
INSERT INTO sample VALUES
 ( 1  ,  0   , current_date)
,( 2  ,  0   , current_date)
,( 3  ,  5   , current_date)
,( 4  ,  0   , current_date)
,( 5  ,  6   , current_date)
;
UPDATE (
    SELECT id, secondaryId
,      ROW_NUMBER() OVER(ORDER BY secondaryId Desc) 
            + (SELECT MAX(id) from sample)      as new_secondaryId
    FROM
        sample s
    WHERE secondaryId = 0
    )
SET secondaryId = new_secondaryId
;

https://www.ibm.com/support/knowledgecenter/en/SSEPGG_11.1.0/com.ibm.db2.luw.sql.ref.doc/doc/r0001022.html