Reputation: 5699
I have a database table, let's call it Foo
. Foo has an id
column (which is long), and some data columns, let's call them Bar1
and Bar2
There is a script that used to work before there was an id
column, that would simply add new stuff into the table like this:
INSERT INTO Foo
SELECT OldBar1, SUM(OldBar2)
FROM OldFoo
GROUP BY OldBar1
Now, after the id
has been added, if I have a new, Foo
table empty initially, then I can do this:
INSERT INTO Foo
SELECT row_number() OVER() as id, OldBar1, SUM(OldBar2)
FROM OldFoo
GROUP BY OldBar1;
And the data in Foo
table will have their id
s equal row numbers.
However, when there is existing data in the Foo
table and I execute the previous query, I get an exception stating that "Key (id)=(1) already exists".
Obviously, I do not want the row_number to look at the source, the OldFoo
table, but rather to the new, Foo
table.
To draw a parallel example in Java, using HashMap<Integer, Foo>
as the repository:
map.put(map.size() + 1, fooObject);
Is there a way to achieve this, to generate the ID which will be the same as row number in the target table?
Upvotes: 0
Views: 5775
Reputation: 1269503
I strongly recommend finding a way to use serial
. However, assuming that there are no other insert
operations occurring on the table, the following should work for you:
INSERT INTO Foo
SELECT (f.maxId + row_number() OVER() )as id, OldBar1, SUM(OldBar2)
FROM OldFoo CROSS JOIN
(SELECT MAX(id) as MAX(ID) FROM Foo) f
GROUP BY OldBar1, f.maxId;
A piece of advice: when using INSERT
always include the column names. So your query should read something like INSERT INTO Foo(Id, OldBar)
. This makes the code easier to maintain and to understand.
Upvotes: 2