I have a table filled in with some values, for example:
CREATE TABLE TABLE1(FOREIGN_ID VARCHAR(5), VV VARCHAR(10));
INSERT INTO TABLE1(FOREIGN_ID, VV) VALUES ('I1', 'XXXXX');
INSERT INTO TABLE1(FOREIGN_ID, VV) VALUES ('I2', 'YYYYY');
INSERT INTO TABLE1(FOREIGN_ID, VV) VALUES ('I2', 'ZZZZZ');
INSERT INTO TABLE1(FOREIGN_ID, VV) VALUES ('I2', 'SSSSS');
INSERT INTO TABLE1(FOREIGN_ID, VV) VALUES ('I2', 'SSSSS');
INSERT INTO TABLE1(FOREIGN_ID, VV) VALUES ('I1', 'TTTTT');
FOREIGN_ID VV
----- ---------
I1 XXXXX
I2 YYYYY
I2 ZZZZZ
I2 SSSSS
I2 SSSSS
I1 TTTTT
And I want to add a new column and make it a part of a primary key:
ALTER TABLE TABLE1 ADD SEQ_NUMBER NUMBER(5) DEFAULT 0 NOT NULL;
ALTER TABLE TABLE1 ADD CONSTRAINT TABLE1_PK PRIMARY KEY (FOREIGN_ID, SEQ_NUMBER);
Of course, the value 0 of SEQ_NUMBER and repeated values of FOREIGN_ID will violate the primary key. How (using Oracle SQL) to set SEQ_NUMBER to 0, 1, 2, ... for each value of SEQ_NUMBER before the constraint is added?
The result could look like this:
FOREIGN_ID VV SEQ_NUMBER
----- --------- -----
I1 XXXXX 0
I2 YYYYY 0
I2 ZZZZZ 1
I2 SSSSS 2
I2 SSSSS 3
I1 TTTTT 1
You can use the row_number
analytic function to compute the rank:
select t.*,
row_number() over (partition by t.foreign_id order by t.vv) - 1 seq_number
from TABLE1 t;
This gives the expected result:
FOREIGN_ID VV SEQ
I1 TTTTT 0
I1 XXXXX 1
I2 SSSSS 0
I2 SSSSS 1
I2 YYYYY 2
I2 ZZZZZ 3
Now there is a problem with analytic functions: you can only use them in select
and group by
clauses because they are computed at the end. This means that you cannot do what you would like to do, ie:
update TABLE1 t
set t.seq_number = row_number() over (partition by t.foreign_id order by t.vv)-1
;
The best workaround I can think of is to create another table from this one:
create table TABLE2 as
select t.foreign_id,
t.vv,
row_number() over (partition by t.foreign_id order by t.vv) - 1 seq_number
from TABLE1 t;
Then you can apply the PK on this one !
ALTER TABLE TABLE2 ADD CONSTRAINT TABLE2_PK PRIMARY KEY (FOREIGN_ID, SEQ_NUMBER);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.