在 Table 的新列中更新序号
Update sequence Number in a new Column in Table
输入
create table myprojects ( startdate date, enddate date, profit number);
insert into myprojects (startdate, enddate,profit ) values(to_date('1/5/2019','mm/dd/yyyy'),to_date('5/1/2019','mm/dd/yyyy'),100);
insert into myprojects (startdate, enddate,profit ) values(to_date('1/6/2019','mm/dd/yyyy'),to_date('2/10/2019','mm/dd/yyyy'),50);
alter table myprojects add ( projectid number );
现在,我已经在此 table 中添加了新的专栏。如何填充此列的值,例如每行 1,2?
使用下面的语句,它工作正常。
CREATE SEQUENCE myseq START WITH 1 INCREMENT BY 1 CACHE 20
/
update myprojects set projectid=myseq.nextval
问题
但是,使用下面的语句它只是将 1 更新为所有记录。为什么?
update myprojects set projectid=(select nvl(max(projectid),0) +1 from myprojects)
有没有什么方法可以在不创建或使用序列的情况下实现同样的效果?
这是使用 merge
的一种方法:
merge into myprojects p
using (select p.*, row_number() over (order by startdate) as x from myprojects p) pp
on (p.rowid = pp.rowid)
when matched then update set projectid = x;
因为 projectid
列的所有值在开始时都是空的,而您正试图在没有任何过滤条件的情况下同时更新所有值。考虑使用 row_number()
分析函数来生成连续的唯一整数:
update myprojects p
set projectid = ( with t as (
select m.*,
row_number()
over (order by startdate, enddate, profit) as rn
from myprojects m
)
select rn
from t
where t.startdate = p.startdate
and t.enddate = p.enddate
and t.profit = p.profit
);
作为替代方式。在 row_number()
函数的 order by
子句和匹配条件 ( t.startdate = p.startdate and t.enddate = p.enddate and t.profit = p.profit
) 的 where
条件以获得更新操作的唯一性。
如果您使用的是 Oracle 12c 及更高版本并且您对标识列感到满意,那么您可以使用以下 alter table 命令,oracle 将为您生成数字。
alter table myprojects add ( projectid number generated always as identity);
在您的实际项目中使用它之前,请阅读 Oracle 文档中的 Identity column
。
干杯!!
输入
create table myprojects ( startdate date, enddate date, profit number);
insert into myprojects (startdate, enddate,profit ) values(to_date('1/5/2019','mm/dd/yyyy'),to_date('5/1/2019','mm/dd/yyyy'),100);
insert into myprojects (startdate, enddate,profit ) values(to_date('1/6/2019','mm/dd/yyyy'),to_date('2/10/2019','mm/dd/yyyy'),50);
alter table myprojects add ( projectid number );
现在,我已经在此 table 中添加了新的专栏。如何填充此列的值,例如每行 1,2?
使用下面的语句,它工作正常。
CREATE SEQUENCE myseq START WITH 1 INCREMENT BY 1 CACHE 20
/
update myprojects set projectid=myseq.nextval
问题
但是,使用下面的语句它只是将 1 更新为所有记录。为什么?
update myprojects set projectid=(select nvl(max(projectid),0) +1 from myprojects)
有没有什么方法可以在不创建或使用序列的情况下实现同样的效果?
这是使用 merge
的一种方法:
merge into myprojects p
using (select p.*, row_number() over (order by startdate) as x from myprojects p) pp
on (p.rowid = pp.rowid)
when matched then update set projectid = x;
因为 projectid
列的所有值在开始时都是空的,而您正试图在没有任何过滤条件的情况下同时更新所有值。考虑使用 row_number()
分析函数来生成连续的唯一整数:
update myprojects p
set projectid = ( with t as (
select m.*,
row_number()
over (order by startdate, enddate, profit) as rn
from myprojects m
)
select rn
from t
where t.startdate = p.startdate
and t.enddate = p.enddate
and t.profit = p.profit
);
作为替代方式。在 row_number()
函数的 order by
子句和匹配条件 ( t.startdate = p.startdate and t.enddate = p.enddate and t.profit = p.profit
) 的 where
条件以获得更新操作的唯一性。
如果您使用的是 Oracle 12c 及更高版本并且您对标识列感到满意,那么您可以使用以下 alter table 命令,oracle 将为您生成数字。
alter table myprojects add ( projectid number generated always as identity);
在您的实际项目中使用它之前,请阅读 Oracle 文档中的 Identity column
。
干杯!!