我有一个表3列的表.没有主键,因此可能存在重复的行.我需要保留一个并删除其他人.任何想法如何做到这一点是Sql Server?
我将SELECT DISTINCT行抛出并将它们放入临时表中,然后删除源表并从temp中复制数据. 编辑:现在使用代码片段!
INSERT INTO TABLE_2 SELECT DISTINCT * FROM TABLE_1 GO DELETE FROM TABLE_1 GO INSERT INTO TABLE_1 SELECT * FROM TABLE_2 GO
添加标识列以充当代理主键,并使用此标识来标识要删除的三行中的两行.
我会考虑在之后保留标识列,或者如果这是某种链接表,则在其他列上创建复合主键.
当您的PK只是所有表列的子集时,以下示例也适用.
(注意:我更喜欢插入另一个代理id列的方法.但也许这个解决方案也很方便.)
首先找到重复的行:
SELECT col1, col2, count(*) FROM t1 GROUP BY col1, col2 HAVING count(*) > 1
如果只有少数,您可以手动删除它们:
set rowcount 1 delete from t1 where col1=1 and col2=1
"rowcount"的值应该是重复次数的n-1倍.在此示例中有2个dulpicates,因此rowcount为1.如果您获得多个重复行,则必须为每个唯一主键执行此操作.
如果您有许多重复项,则将每个键复制一次到anoher表中:
SELECT col1, col2, col3=count(*) INTO holdkey FROM t1 GROUP BY col1, col2 HAVING count(*) > 1
然后复制密钥,但删除重复项.
SELECT DISTINCT t1.* INTO holddups FROM t1, holdkey WHERE t1.col1 = holdkey.col1 AND t1.col2 = holdkey.col2
在你的钥匙中,你现在拥有独特的钥匙.检查您是否收到任何结果:
SELECT col1, col2, count(*) FROM holddups GROUP BY col1, col2
从原始表中删除重复项:
DELETE t1 FROM t1, holdkey WHERE t1.col1 = holdkey.col1 AND t1.col2 = holdkey.col2
插入原始行:
INSERT t1 SELECT * FROM holddups
btw和完整性:在Oracle中有一个可以使用的隐藏字段(rowid):
DELETE FROM our_table WHERE rowid not in (SELECT MIN(rowid) FROM our_table GROUP BY column1, column2, column3... ;
请参阅:Microsoft知识网站