Die Frage ist falsch, sie sollte lauten: “Wie kann ich das verhindern?”, denn Du hast a) Redundanz und b) Aufwand, das zu pflegen. Was passiert, wenn ein neues Tupel (c,d) dazukommt?
Um Dir dennoch einen Ansatz zu geben:
test=*# select * from rajanski ;
a | b
---+---
a | b
a | b
a | b
c | d
c | d
e | f
e | f
e | f
(8 rows)
Time: 0,244 ms
test=*# select a, b, row_number() over () from (select distinct on (a, b) a, b from rajanski) foo ;
a | b | row_number
---+---+------------
a | b | 1
c | d | 2
e | f | 3
(3 rows)
Hallo ja das mit der Redundanz und Aufwand ist mir völlig klar, wurde aber hier vom Auftraggeber so entschieden und hat wirklich auch gute Gründe. Und neue Tupel kommen nicht dazu, das wird einmal eingelesen und bleibt dann so…
Die Tabelle soll bis auf die hinzugekommene ID-Spalte vom Umfang her gleich bleiben:
a | b | ID
—±–±--
a | b | 1
a | b | 1
a | b | 1
c | d | 2
c | d | 2
e | f | 3
e | f | 3
e | f | 3
postgres=> select *
postgres-> from rajanski;
a | b
---+---
a | b
a | b
a | b
a | b
c | d
c | d
e | f
e | f
e | f
(9 rows)
postgres=> alter table rajanski add id integer;
ALTER TABLE
postgres=> update rajanski
postgres-> set id = nid
postgres-> from (select a, b, nid
postgres(> from (
postgres(> select *,
postgres(> sum(group_flag) over (order by a||b) as nid
postgres(> from (
postgres(> select *,
postgres(> case
postgres(> when lag(a||b) over (order by a,b) = a||b then null
postgres(> else 1
postgres(> end as group_flag
postgres(> from rajanski
postgres(> ) t1
postgres(> ) t2
postgres(> ) t3
postgres-> where t3.a = rajanski.a
postgres-> and t3.b = rajanski.b
postgres-> ;
UPDATE 9
postgres=> commit;
COMMIT
postgres=> select * from rajanski;
a | b | id
---+---+----
a | b | 1
a | b | 1
a | b | 1
a | b | 1
c | d | 2
c | d | 2
e | f | 3
e | f | 3
e | f | 3
(9 rows)
postgres=>