删除表中的重复项
数据库类型为PostGres 8.3。删除表中的重复项
如果我写道:
SELECT field1, field2, field3, count(*)
FROM table1
GROUP BY field1, field2, field3 having count(*) > 1;
我有一些行有超过1.如何取出重复计数(我还是想1排为他们每个人的,而不是排+1。 ..我不想将它们全部删除)
例:
1-2-3
1-2-3
1-2-3
2-3-4
4-5-6
应该改为:
1-2-3
2-3-4
4-5-6
我发现的唯一答案是there,但我想知道如果我能做到这一点没有哈希列。
警告 我没有用一个唯一的编号PK了,所以我不能使用分钟(...)的技术。 PK是3个领域。
这是所有表应具有主键的许多原因之一(不一定是ID号或IDENTITY,而是一个或多个列的唯一标识行和在数据库中实施其唯一性的组合) 。
最好的办法是这样的:
SELECT field1, field2, field3, count(*)
INTO temp_table1
FROM table1
GROUP BY field1, field2, field3 having count(*) > 1
DELETE T1
FROM table1 T1
INNER JOIN (SELECT field1, field2, field3
FROM table1
GROUP BY field1, field2, field3 having count(*) > 1) SQ ON
SQ.field1 = T1.field1 AND
SQ.field2 = T1.field2 AND
SQ.field3 = T1.field3
INSERT INTO table1 (field1, field2, field3)
SELECT field1, field2, field3
FROM temp_table1
DROP TABLE temp_table1
我目前正在尝试你的建议。 +1 – 2008-10-28 15:25:09
它工作thx,我已经修改DELETE T1的一些东西不起作用,我不得不把T1之后的T1作为T1。很少有这样的事情。但这个解决方案在这里很快并且很成功。 – 2008-10-28 16:33:14
一个可能的答案是:
CREATE <temporary table> (<correct structure for table being cleaned>);
BEGIN WORK; -- if needed
INSERT INTO <temporary table> SELECT DISTINCT * FROM <source table>;
DELETE FROM <source table>
INSERT INTO <source table> SELECT * FROM <temporary table>;
COMMIT WORK; -- needed
DROP <temporary table>;
我不知道的“工作”是否需要在交易声明,亦无论是明确的开始,有必要在PostgreSQL的。但是这个概念适用于任何DBMS。
唯一要注意的是参照约束,特别是触发删除操作。如果存在的话,这可能不太令人满意。
这将使用OID对象ID(如果该表是用它创建):
DELETE FROM table1
WHERE OID NOT IN (SELECT MIN (OID)
FROM table1
GROUP BY field1, field2, field3)
嗯,我会误解的东西,但我我会说:
SELECT DISTINCT field1,field2,field3 FROM table1
太容易变好了? ^^
使用TSQL,不知道如果Postgres支持用临时表,但你可以选择到一个临时表,然后通过循环和删除和插入您的结果放回原
-- **Disclaimer** using TSQL
-- You could select your records into a temp table with a pk
Create Table #dupes
([id] int not null identity(1,1), f1 int, f2 int, f3 int)
Insert Into #dupes (f1,f2,f3) values (1,2,3)
Insert Into #dupes (f1,f2,f3) values (1,2,3)
Insert Into #dupes (f1,f2,f3) values (1,2,3)
Insert Into #dupes (f1,f2,f3) values (2,3,4)
Insert Into #dupes (f1,f2,f3) values (4,5,6)
Insert Into #dupes (f1,f2,f3) values (4,5,6)
Insert Into #dupes (f1,f2,f3) values (4,5,6)
Insert Into #dupes (f1,f2,f3) values (7,8,9)
Select f1,f2,f3 From #dupes
Declare @rowCount int
Declare @counter int
Set @counter = 1
Set @rowCount = (Select Count([id]) from #dupes)
while (@counter < @rowCount + 1)
Begin
Delete From #dupes
Where [Id] <>
(Select [id] From #dupes where [id][email protected])
and
(
[f1] = (Select [f1] from #dupes where [id][email protected])
and
[f2] = (Select [f2] from #dupes where [id][email protected])
and
[f3] = (Select [f3] from #dupes where [id][email protected])
)
Set @counter = @counter + 1
End
Select f1,f2,f3 From #dupes -- You could take these results and pump them back into --your original table
Drop Table #dupes
测试这对MS SQL Server 2000.不熟悉Postgres的选项,但也许这会导致你在一个正确的方向。
这是我发现的最简单的方法:
Postgre SQL语法:
CREATE TABLE tmp AS SELECT distinct * FROM table1
truncate table table1
insert into table1 select * from tmp
drop table tmp
T-SQL语法:
select distinct * into #tmp from table1
truncate table table1
insert into table1 select * from #tmp
drop table #tmp
一个好的Answer对于这个问题,但对于SQL Server。它使用SQL Server提供的ROWCOUNT,以达到良好的效果。我从来没有使用PostgreSQL,因此不知道PostgreSQL中ROWCOUNT的等价物。
我不确定我是否理解正确。你说“PK是3场” - 那么你怎么像表1-2-3中的重复记录一样。纠正我,如果我错了。 – 2008-10-28 15:02:00
PK是在3个领域,我们必须删除他们的合并(长篇故事),现在我们需要把它放回去。我们有一些我们想要起飞的重复。 – 2008-10-28 15:10:31