1

I have a "raw" table that looks like this (among other many fields):

 team_id |        team_name        
---------+-------------------------
       1 | Team1
       1 | Team1
       2 | Team2
       2 | Team2

I want to extract the team names and their id codes and create another table for them, so I created:

    CREATE TABLE teams (
        team_id integer NOT NULL,
        team_name varchar(50) NOT NULL,
        CONSTRAINT team_pkey PRIMARY KEY (team_id)
);

And I am planning to copy the data from the old table to the recently created one like this:

INSERT INTO teams(team_id,team_name)                                        
SELECT team_id,team_name FROM rawtable 
GROUP BY team_id, team_name; 

At first I wasn't adding the GROUP BY part, and I was getting a message:

ERROR:  duplicate key value violates unique constraint "team_pkey"

I added the GROUP BY so it doesn't try to insert more than one row for the same team, but the problem still persist and I keep getting the same message.

I don't understand what is causing it. It looks like I am inserting single non duplicate rows into the table. What's the best way to fix this?

1
  • Are you sure, so it is how you describe. Your data, your SQL is working for me without problems. Commented May 30, 2015 at 17:10

5 Answers 5

1

If two different teams with the same id are in raw_table e.g. (1, 'foo') and (1, 'bar') the group by will still return both, because those two are different.

If you just want to pick one of the rows for duplicate values of team_id then you should use something like this:

insert into teams (team_id,team_name)  
select distinct on (team_id) team_id, team_name
from rawtable
order by team_id;

The Postgres specific distinct on operator will make sure that only distinct values for team_id are returned.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, actually that was the problem I had. I didn't need to change my statement to find the bad row because I accidentally saw it, but I will mark your answer as accepted because of the useful example I can use for the future.
1

My best guess is that you have the same team_id for more then one team_name at least somewhere in your table. Try to add `Having count(*)=1 to your select statement

3 Comments

having count(*) = 1 won't help if two different team_name have the same team_id because they are still considered different by a group by team_id, team_name
Actually that was it! I didn't copy the original raw table here because it was really long, but it seems that the id column had not been checked for duplicates, so there was one faulty row. I didn't even change the select as you suggest, because I just accidentally saw the offending row....
Oops, correct. Using max as joachim wrote is a better suggestion.
1

Since the team_id is unique in the destination table, two separate team names with the same id will create duplicates, one row for each name.

A simple fix is to group by team_id so that you only get a single row per id, and pick one of the names the team has (here we somewhat arbitrarily use MAX to get the last in alphabetical order)

INSERT INTO teams(team_id,team_name)                                        
 SELECT team_id, MAX(team_name) FROM rawtable 
 GROUP BY team_id

Comments

0

One of your Team1 or Team2 probably has some extra spaces or nonprintable characters. This would cause your group by to return multiple rows for Team_ID 1 or 2 causing the problem.

2 Comments

This is sample data. For only 2 teams he would have inserted them manually faster then writing the question...
Er... so was Team1 and Team2 in my example. The point was there could be extra spaces or nonprintable character causing his group by to return multiple rows.
0

Try to use distinct in your query :

insert into teams (team_id,team_name) select distinct on (team_id) team_id, team_name from order by team_id;

1 Comment

SELECT DISTINCT a,b .. and SELECT a,b GROUP BY a, b are equal.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.