I have a table like below:
CREATE TABLE "table" (
"index" serial PRIMARY KEY,
"number" integer
);
With these rows:
INSERT INTO "table" ("number") VALUES
(1), (2), (2), (3), (4), (4), (4), (5), (13), (13), (17);
I want to update duplicate values to the next free integer number (except for the 1st one).
For this case it should be like:
(1), (2), (3), (4), (5), (6), (7), (8), (13), (14), (17)
How could the UPDATE work?
Every next free number potentially depends on all previous updates in the process. So this needs, at its heart, a procedural solution.
The best solution depends on cardinalities and the frequency of duplicates and gaps. According to your sample I assume:
The below code works in any case, but best for the stated assumptions.
fiddle
This PL/pgSQL code block first creates a temporary table of free numbers (
free) in the range of the given tabletbl. I (arbitrarily) add 10 more numbers after the highest one. If you might need more than 10 additional numbers past the highest one, you need to do more.If that table comes out big, create an index.
Then run through all duplicates, and assign the next free number, consuming it.
Obviously, this algorithm assumes no concurrent writes.