Reputation: 1087
Input
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 );
Now, I have added the new column in this table. How to Populate the values for this column like 1,2 for each row?
Using the below statement, it works fine.
CREATE SEQUENCE myseq START WITH 1 INCREMENT BY 1 CACHE 20
/
update myprojects set projectid=myseq.nextval
Question
However,using the below statement it just updates 1 to all records. Why?
update myprojects set projectid=(select nvl(max(projectid),0) +1 from myprojects)
Is there any way to achieve the same without creating or using sequence?
Upvotes: 0
Views: 1623
Reputation: 35930
If you are using Oracle 12c and above and if you are happy with identity column then you can use the following alter table command and oracle will generate numbers for you.
alter table myprojects add ( projectid number generated always as identity);
Please read about Identity column
from Oracle docs before using it in your actual project.
Cheers!!
Upvotes: 2
Reputation: 65433
Because all values for projectid
column are null at the beginning and you're trying to update all values at the same time without any filtering condition . Consider using row_number()
analytic function to produce consecutive unique integers :
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
);
as an alterative way. All the columns of the table(startdate
, enddate
, profit
) used within the row_number()
function's order by
clause and within the matching conditions (t.startdate = p.startdate and t.enddate = p.enddate and t.profit = p.profit
) of where
condition to get the uniqueness for the updating operation.
Upvotes: 2
Reputation: 1271171
Here is one method using 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;
Upvotes: 1