在日常维护 经常会有一些表少某些索引约束导致一些表出现重复行,使后期再转换的时候多了数据,导致数据不对。
今天发个删除完全一样的数据的记录。
-- 首先创建测试表
CREATE TABLE test_delete(
name varchar(10),
value INT
);
go
CREATE TABLE test_delete(
name varchar(10),
value INT
);
go
-- 测试数据,其中 张三100 与 王五80 是完全一样的
INSERT INTO test_delete
SELECT '张三',100
UNION ALL SELECT '张三',100
UNION ALL SELECT '李四',80
UNION ALL SELECT '王五',80
UNION ALL SELECT '赵六',90
UNION ALL SELECT '赵六',70
go
INSERT INTO test_delete
SELECT '张三',100
UNION ALL SELECT '张三',100
UNION ALL SELECT '李四',80
UNION ALL SELECT '王五',80
UNION ALL SELECT '赵六',90
UNION ALL SELECT '赵六',70
go
-- 首先查询一下, ROW_NUMBER 效果是否满足预期
SELECT
ROW_NUMBER() OVER (PARTITION BY name,value ORDER BY (SELECT 1) ) AS no,
name,
value
FROM
test_delete
no name value
----- ---------- -----------
1 李四 80
1 王五 80
2 王五 80
1 张三 100
2 张三 100
1 赵六 70
1 赵六 90
----- ---------- -----------
1 李四 80
1 王五 80
2 王五 80
1 张三 100
2 张三 100
1 赵六 70
1 赵六 90
从结果上可以看到,如果有重复的,完全一样的话, no 是有大于1的。
-- 创建视图
CREATE VIEW tmp_view AS
SELECT
ROW_NUMBER() OVER (PARTITION BY name,
value
FROM
test_delete
-- 删除 视图中的 no 不等于 1 的数据。
1> DELETE FROM tmp_view WHERE no != 1
2> go
1> DELETE FROM tmp_view WHERE no != 1
2> go
(2 行受影响)
1>
2> select * from test_delete;
3> go
name value
---------- -----------
张三 100
李四 80
王五 80
赵六 90
赵六 70
1>
2> select * from test_delete;
3> go
name value
---------- -----------
张三 100
李四 80
王五 80
赵六 90
赵六 70
(5 行受影响)
结果看上去是满足预期的。
sql SERVER 2000
有两个意义上的重复记录,一是完全重复的记录,也即所有字段均重复的记录,二是部分关键字段重复的记录,比如Name字段重复,而其他字段不一定重复或都重复可以忽略。
就可以得到无重复记录的结果集。
如果该表需要删除重复的记录(重复记录保留1条),可以按以下方法删除
select distinct * into #Tmp from tableName
drop table tableName
select * into tableName from #Tmp
drop table #Tmp
select distinct * into #Tmp from tableName
drop table tableName
select * into tableName from #Tmp
drop table #Tmp
2、这类重复问题通常要求保留重复记录中的第一条记录,操作方法如下
假设有重复的字段为Name,Address,要求得到这两个字段唯一的结果集
select identity(int,1,1) as autoID,* into #Tmp from tableName
select min(autoID) as autoID into #Tmp2 from #Tmp group by Name,autoID
select * from #Tmp where autoID in(select autoID from #tmp2)
select identity(int,1,1) as autoID,* into #Tmp from tableName
select min(autoID) as autoID into #Tmp2 from #Tmp group by Name,autoID
select * from #Tmp where autoID in(select autoID from #tmp2)
Oracle 的处理办法
使用 Oracle 的 ROWID 来删除的处理步骤如下:
sql> CREATE TABLE test_delete(
2 name varchar(10),
3 value INT
4 );
表已创建。
2 name varchar(10),
3 value INT
4 );
表已创建。
sql> INSERT INTO test_delete
2 SELECT '张三',100 FROM dual
3 UNION ALL SELECT '张三',100 FROM dual
4 UNION ALL SELECT '李四',80 FROM dual
5 UNION ALL SELECT '王五',80 FROM dual
6 UNION ALL SELECT '王五',80 FROM dual
7 UNION ALL SELECT '赵六',90 FROM dual
8 UNION ALL SELECT '赵六',70 FROM dual;
已创建7行。
2 SELECT '张三',100 FROM dual
3 UNION ALL SELECT '张三',100 FROM dual
4 UNION ALL SELECT '李四',80 FROM dual
5 UNION ALL SELECT '王五',80 FROM dual
6 UNION ALL SELECT '王五',80 FROM dual
7 UNION ALL SELECT '赵六',90 FROM dual
8 UNION ALL SELECT '赵六',70 FROM dual;
已创建7行。
sql> SELECT
2 ROWID,
3 name,
4 value
5 FROM
6 test_delete;
ROWID NAME VALUE
------------------ ---------- ----------
AAAM2mAAGAAAAOXAAA 张三 100
AAAM2mAAGAAAAOXAAB 张三 100
AAAM2mAAGAAAAOXAAC 李四 80
AAAM2mAAGAAAAOXAAD 王五 80
AAAM2mAAGAAAAOXAAE 王五 80
AAAM2mAAGAAAAOXAAF 赵六 90
AAAM2mAAGAAAAOXAAG 赵六 70
已选择7行。
2 ROWID,
3 name,
4 value
5 FROM
6 test_delete;
ROWID NAME VALUE
------------------ ---------- ----------
AAAM2mAAGAAAAOXAAA 张三 100
AAAM2mAAGAAAAOXAAB 张三 100
AAAM2mAAGAAAAOXAAC 李四 80
AAAM2mAAGAAAAOXAAD 王五 80
AAAM2mAAGAAAAOXAAE 王五 80
AAAM2mAAGAAAAOXAAF 赵六 90
AAAM2mAAGAAAAOXAAG 赵六 70
已选择7行。
sql> DELETE
2 test_delete
3 WHERE
4 (name,value)
5 IN (SELECT
6 name,value
7 FROM
8 test_delete
9 GROUP BY
10 name,value
11 HAVING COUNT(1) > 1)
12 AND rowid NOT IN
13 (SELECT
14 MIN(rowid)
15 FROM
16 test_delete
17 GROUP BY
18 name,value
19 HAVING
20 COUNT(1) > 1);
2 test_delete
3 WHERE
4 (name,value)
5 IN (SELECT
6 name,value
7 FROM
8 test_delete
9 GROUP BY
10 name,value
11 HAVING COUNT(1) > 1)
12 AND rowid NOT IN
13 (SELECT
14 MIN(rowid)
15 FROM
16 test_delete
17 GROUP BY
18 name,value
19 HAVING
20 COUNT(1) > 1);
已删除2行。
sql> SELECT
2 ROWID,
4 value
5 FROM
6 test_delete;
2 ROWID,
4 value
5 FROM
6 test_delete;
ROWID NAME VALUE ------------------ ---------- ---------- AAAM2mAAGAAAAOXAAA 张三 100 AAAM2mAAGAAAAOXAAC 李四 80 AAAM2mAAGAAAAOXAAD 王五 80 AAAM2mAAGAAAAOXAAF 赵六 90 AAAM2mAAGAAAAOXAAG 赵六 70
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。