我有一个表有四个字段:ID自动增量,一个字符串和两个整数。 我想要做类似的东西:如何从数据库中删除重复项?
select count(*) from table group by string
,然后用结果来巩固它们是大于1
也就是说,走哪都行数大于1的所有指控,并将数据库中所有这些行(具有相同的字符串)替换为单行,ID无关紧要,并且这两个整数是所有行数大于1的所有行的总和。
这可能使用一些简单的查询吗?
谢谢。
我有一个表有四个字段:ID自动增量,一个字符串和两个整数。 我想要做类似的东西:如何从数据库中删除重复项?
select count(*) from table group by string
,然后用结果来巩固它们是大于1
也就是说,走哪都行数大于1的所有指控,并将数据库中所有这些行(具有相同的字符串)替换为单行,ID无关紧要,并且这两个整数是所有行数大于1的所有行的总和。
这可能使用一些简单的查询吗?
谢谢。
如果您可以阻止其他用户更新表格,那么这很容易。
-- We're going to add records before deleting old ones, so keep track of which records are old.
DECLARE @OldMaxID INT
SELECT @OldMaxID = MAX(ID) FROM table
-- Combine duplicate records into new records
INSERT table (string, int1, int2)
SELECT string, SUM(int1), SUM(int2)
FROM table
GROUP BY string
HAVING COUNT(*) > 1
-- Delete records that were used to make combined records.
DELETE FROM table
WHERE ID <= @OldMaxID
GROUP BY string
HAVING COUNT(*) > 1
有一个简单的方法来做到这一点。只要将像
id NOT IN (select id from table group by string)
在where语句
,这将通过选择只是count > 0
些,然后选择所需的资金只选择复制
开始:
select * from (
select count(*), string_col, sum(int_col_1), sum(int_col_2)
from my_table
group by string_col
) as foo where count > 1
后我会将这些数据放入临时表中,删除不需要的行,并将临时表中的数据插入原始表中。
我建议插入临时表数据按字符串分组,并伴有min(id)其中有重复的地方。然后更新原始表格,其中id = min(id),并删除字符串匹配但id不匹配。
insert into temp
select string, min(id) id, sum(int1) int1, sum(int2) int2
from table
group by string
having count(*) > 1
update table, temp
set table.int1 = temp.int1,
table.int2 = temp.int2
where table.id = temp.id
-- Works because there is only one record given a string in temp
delete table
where exists (select null from temp where temp.string = table.string and temp.id <> table.id)
备份是强制性的:-)和一个交易也。
你可以在两个查询中完成所有工作,没有临时表。但是您需要重复运行DELETE查询,因为它一次只能删除1个重复项。所以如果一行有三份,你需要运行两次。但是你可以运行它直到没有更多的结果。
更新您要保留的重复行以包含计数/总和。
UPDATE tablename JOIN (
SELECT min(id) id,sum(int1) int1,sum(int2) int2
FROM tablename GROUP BY string HAVING c>1
) AS dups ON tablename.id=dups.id
SET tablename.int1=dups.int1, tablename.int2
然后,您可以在DELETE查询中使用同一个SELECT查询,使用多表语法。
DELETE tablename FROM tablename
JOIN (SELECT max(id) AS id,count(*) c FROM tablename GROUP BY string HAVING c>1) dups
ON tablename.id=dups.id
只需运行DELETE,直到没有行返回(0受影响的行)。
您可以在视图中获得这样的信息:
CREATE VIEW SummarizedData (StringCol, IntCol1, IntCol2, OriginalRowCount) AS
SELECT StringCol, SUM(IntCol1), SUM(IntCol2), COUNT(*)
FROM TableName
GROUP BY StringCol
这将创建一个虚拟表你想要的信息。它将包含仅有一个StringCol值实例的行 - 如果您不希望这些行将短语HAVING COUNT(*) > 1
添加到查询的末尾。
有了这个方法,你可以保持原有的表和汇总数据只是读,也可以创建具有相应列从SummarizedData
一个空表结构和INSERT
到新表中得到一个“真正”的表中的数据。
这不符合要求,其余行中的整数被更新为具有该组中所有行的所有整数的总和(在删除之前) – 2012-03-12 00:06:07
感谢您指出这一点,错过了这部分问题。编辑添加UPDATE查询以首先保存总和。 – 2012-03-12 02:25:12