我必须从没有主键或唯一约束的表中清除记录。从没有唯一列的表中删除部分重复项
表定义:
create table person(
name text,
staff_id integer,
work_code text,
location
);
不出所料,它含有大量的重复和部分重复的。 将记录转换为唯一集合的最佳方式是什么?我不必关心除名称和职员以外的其他专栏
我必须从没有主键或唯一约束的表中清除记录。从没有唯一列的表中删除部分重复项
表定义:
create table person(
name text,
staff_id integer,
work_code text,
location
);
不出所料,它含有大量的重复和部分重复的。 将记录转换为唯一集合的最佳方式是什么?我不必关心除名称和职员以外的其他专栏
正如你
不必在意除了名字等栏目和staff_id
这可能是你的程序来清理表:
1 )创建一个临时表独特行:
CREATE TEMP TABLE p_tmp AS
SELECT DISTINCT ON (name, staff_id)
name, staff_id, work_code, location
FROM person
ORDER BY name, staff_id, work_code, location;
我随意选择“第一行每(name, staff_id)
- 最小work_code
和匹配location
。
2)空表:
TRUNCATE person;
3)重新插入独特的元组:
INSERT INTO person SELECT * FROM p_tmp;
确保,受骗者不悄悄潜回里添加一个代理主键:
ALTER TABLE person ADD COLUMN person_id serial PRIMARY KEY;
ALTER TABLE person ADD UNIQUE (name, staff_id);
或者只需添加一个多列主键:
ALTER TABLE person ADD PRIMARY KEY (name, staff_id);
临时表将在会话结束时自动丢弃。
当然,所有这一切最好在一个transaction内完成,所以在不太可能出现半途遇到问题的情况下不会丢失任何东西。有些客户端会自动执行一次执行的一批SQL语句。
当然'max'比'min'更好;使空值最不可能被选中。 – Ben 2012-01-01 20:55:04
@Ben:max()和min()都不会在**任何**值上选择NULL。 – 2012-01-01 21:05:20
@ErwinBrandstetter谢谢你,它很好地工作 – 2012-01-02 04:47:19
也许这样?
select t.name, t.staff_id, t.work_code, t.location
from (
select name, staff_id, work_code, location, count(*) nr
from person
group by name, staff_id, work_code, location
) t
where t.nr > 1;
我很抱歉,我的意思是我需要摆脱部分重复行,但保留与所有其他值的1唯一行以及。我尝试不同,但它仍然返回所有行 – 2012-01-01 19:27:27
请参阅后编辑,做它回答您的需求? – fge 2012-01-01 19:33:45
它抱怨说我需要将所有t。*列包含在group by子句中。当我这样做时,它不返回任何行。我测试了子查询,并且“nr”列从不包含大于1的值。 – 2012-01-01 19:53:10
你称之为“部分重复”? – fge 2012-01-01 19:17:29
@ work_code和location_fge变体,我只需要保留name和staff_id – 2012-01-01 19:18:47
你真的关心哪些值会得到最终结果吗? – fge 2012-01-01 19:19:34