示例表:
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
有没有人建议采用不同的方法来解决这个问题?我现在正在遭受隧道视觉......
答案 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
;