Обновление с увеличением столбца - PullRequest
0 голосов
/ 12 мая 2018

Пример таблицы:

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 голосов
/ 12 мая 2018

Для метода 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;
0 голосов
/ 14 мая 2018

Вы также можете UPDATE a SELECT (хорошо "fullselect"), что, вероятно, является самым подходящим решением здесь

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

0 голосов
/ 12 мая 2018

Вы можете использовать оператор 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...