简体   繁体   English

在表的新列中更新序列号

[英]Update sequence Number in a new Column in Table

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? 如何为每一行填充此列的值(例如1,2)?

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

  1. However,using the below statement it just updates 1 to all records. 但是,使用以下语句只会将1更新为所有记录。 Why? 为什么?

     update myprojects set projectid=(select nvl(max(projectid),0) +1 from myprojects) 
  2. Is there any way to achieve the same without creating or using sequence? 有什么方法可以在不创建或不使用序列的情况下实现相同目标?

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. 如果您使用的是Oracle 12c及更高版本,并且对Identity列满意,则可以使用以下alter table命令,并且oracle会为您生成数字。

alter table myprojects add ( projectid number generated always as identity);

db<>fiddle demo db <> fiddle演示

Please read about Identity column from Oracle docs before using it in your actual project. 在实际项目中使用它之前,请先阅读Oracle文档中的“ Identity column

Cheers!! 干杯!!

Here is one method using merge : 这是使用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;

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 . 因为projectid列的所有值在开始都是空的,所以您试图同时更新所有值而没有任何过滤条件。 Consider using row_number() analytic function to produce consecutive unique integers : 考虑使用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
                     ); 

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. row_number()函数的order by子句以及匹配条件( t.startdate = p.startdate and t.enddate = p.enddate and t.profit = p.profit )中使用的表的所有列( startdateenddateprofitt.startdate = p.startdate and t.enddate = p.enddate and t.profit = p.profit的) where条件得到了更新操作的唯一性。

Demo 演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM