无法在PostgreSQL中插入具有主键约束的字段

无法在PostgreSQL中插入具有主键约束的字段,sql,postgresql,constraints,Sql,Postgresql,Constraints,我有一个“原始”表,看起来像这样(在其他许多字段中): 我想提取团队名称及其id代码,并为其创建另一个表,因此我创建了: CREATE TABLE teams ( team_id integer NOT NULL, team_name varchar(50) NOT NULL, CONSTRAINT team_pkey PRIMARY KEY (team_id) ); 我计划将数据从旧表复制到最近创建的表中,如下所示: INSERT IN

我有一个“原始”表,看起来像这样(在其他许多字段中):

我想提取团队名称及其id代码,并为其创建另一个表,因此我创建了:

    CREATE TABLE teams (
        team_id integer NOT NULL,
        team_name varchar(50) NOT NULL,
        CONSTRAINT team_pkey PRIMARY KEY (team_id)
);
我计划将数据从旧表复制到最近创建的表中,如下所示:

INSERT INTO teams(team_id,team_name)                                        
SELECT team_id,team_name FROM rawtable 
GROUP BY team_id, team_name; 
起初,我没有添加
groupby
部分,而是收到一条消息:

ERROR:  duplicate key value violates unique constraint "team_pkey"
我添加了
groupby
,这样它就不会尝试为同一个团队插入多行,但问题仍然存在,我一直收到相同的消息


我不明白是什么引起的。看起来我正在向表中插入单个不重复的行。解决这个问题的最好方法是什么

尝试在查询中使用distinct:

插入到团队(团队id,团队名称)中选择distinct on(团队id) 团队id,按团队id排序的订单中的团队名称


您的一个团队1或团队2可能有一些额外的空格或不可打印的字符。这将导致您的group by为团队ID 1或2返回多行,从而导致该问题。

我的最佳猜测是,您的表中至少有一个团队名称与多个团队ID相同。如果两个具有相同id的不同团队在
原始表中,例如
(1,'foo')
(1,'bar')
中,请尝试将'Having count(*)=1添加到select语句中,
group by
仍将同时返回这两个,因为这两个团队不同

如果您只想为
team_id
的重复值选择一行,那么您应该使用如下内容:

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

Postgres specific
distinct on
操作符将确保只返回
团队id
的不同值。

由于团队id在目标表中是唯一的,因此具有相同id的两个独立团队名称将创建重复项,每个名称对应一行

一个简单的解决方法是按团队id分组,这样每个id只能得到一行,然后选择团队的一个名称(这里我们随意使用MAX按字母顺序获得最后一行)


你确定吗,这就是你所描述的。您的数据、SQL对我来说没有问题。请选择不同的a、b。。如果两个不同的
团队名称
具有相同的
团队id
,则使用count(*)=1将不会有帮助,因为a
团队id、团队名称
仍然认为它们不同,实际上就是这样!我没有在这里复制原始表,因为它非常长,但似乎没有检查id列是否有重复项,因此有一行有错误。我甚至没有按照你的建议更改选择,因为我只是意外地看到了有问题的行……哦,对了。像约阿希姆写的那样使用max是一个更好的建议。谢谢你,实际上这就是我遇到的问题。我不需要更改我的语句来查找错误行,因为我意外地看到了它,但我会将您的答案标记为已接受,因为我可以在将来使用有用的示例。这是示例数据。如果只有两个团队,他会手动插入,比写问题更快…呃。。。在我的例子中,团队1和团队2也是如此。关键是可能有额外的空格或不可打印字符导致他的分组返回多行。
insert into teams (team_id,team_name)  
select distinct on (team_id) team_id, team_name
from rawtable
order by team_id;
INSERT INTO teams(team_id,team_name)                                        
 SELECT team_id, MAX(team_name) FROM rawtable 
 GROUP BY team_id