首页 > 数据库 > 数据库开发技术 > Oracle如何查找并删除重复记录
CREATE TABLE people (
id integer GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
name varchar2(50) NOT NULL,
email varchar2(100) NOT NULL
);
INSERT INTO people(name, email)
VALUES ('张三', 'zhangsan@test.com');
INSERT INTO people(name, email)
VALUES ('李四', 'lisi@test.com');
INSERT INTO people(name, email)
VALUES ('王五', 'wangwu@test.com');
INSERT INTO people(name, email)
VALUES ('李斯', 'lisi@test.com');
INSERT INTO people(name, email)
VALUES ('王五', 'wangwu@test.com');
INSERT INTO people(name, email)
VALUES ('王五', 'wangwu@test.com');
SELECT * FROM people;
ID|NAME |EMAIL |
--|-----|-----------------|
1|张三 |zhangsan@test.com|
2|李四 |lisi@test.com |
3|王五 |wangwu@test.com |
4|李斯 |lisi@test.com |
5|王五 |wangwu@test.com |
6|王五 |wangwu@test.com |
ALTER TABLE people ADD CONSTRAINT uk_people_email UNIQUE (email);
ERROR at line 1:
ORA-02299: cannot validate (TONY.UK_PEOPLE_EMAIL) - duplicate keys found
SELECT email, count(email)
FROM people
GROUP BY email
HAVING count(email) > 1;
EMAIL |COUNT(EMAIL)|
---------------|------------|
lisi@test.com | 2|
wangwu@test.com| 3|
SELECT *
FROM people
WHERE email IN (
SELECT email
FROM people
GROUP BY email
HAVING count(email) > 1)
ORDER BY email;
ID|NAME |EMAIL |
--|-----|---------------|
2|李四 |lisi@test.com |
4|李斯 |lisi@test.com |
3|王五 |wangwu@test.com|
5|王五 |wangwu@test.com|
6|王五 |wangwu@test.com|
WITH d AS (
SELECT email
FROM people
GROUP BY email
HAVING count(email) > 1)
SELECT p.*
FROM people p
JOIN d ON (d.email = p.email)
ORDER BY p.email;
ID|NAME |EMAIL |
--|-----|---------------|
2|李四 |lisi@test.com |
4|李斯 |lisi@test.com |
3|王五 |wangwu@test.com|
5|王五 |wangwu@test.com|
6|王五 |wangwu@test.com|
SELECT DISTINCT p.*
FROM people p
JOIN people d ON p.email = d.email
WHERE p.id <> d.id
ORDER BY p.email;
ID|NAME |EMAIL |
--|-----|---------------|
2|李四 |lisi@test.com |
4|李斯 |lisi@test.com |
3|王五 |wangwu@test.com|
5|王五 |wangwu@test.com|
6|王五 |wangwu@test.com|
SELECT *
FROM people
WHERE (name, email) IN (
SELECT name, email
FROM people
GROUP BY name, email
HAVING count(1) > 1)
ORDER BY email;
ID|NAME |EMAIL |
--|-----|---------------|
3|王五 |wangwu@test.com|
5|王五 |wangwu@test.com|
6|王五 |wangwu@test.com|
WITH d AS (
SELECT name, email
FROM people
GROUP BY name, email
HAVING count(*) > 1)
SELECT p.*
FROM people p
JOIN d ON (d.name = p.name AND d.email = p.email)
ORDER BY p.email;
ID|NAME |EMAIL |
--|-----|---------------|
3|王五 |wangwu@test.com|
5|王五 |wangwu@test.com|
6|王五 |wangwu@test.com|
SELECT id, name, email, count(*) over (partition by email) cnt
FROM people;
ID|NAME |EMAIL |CNT|
--|-----|-----------------|---|
4|李斯 |lisi@test.com | 2|
2|李四 |lisi@test.com | 2|
6|王五 |wangwu@test.com | 3|
3|王五 |wangwu@test.com | 3|
5|王五 |wangwu@test.com | 3|
1|张三 |zhangsan@test.com| 1|
WITH d AS (
SELECT id, name, email,
count(*) over (partition by email) cnt
FROM people)
SELECT *
FROM d
WHERE cnt > 1
ORDER BY id;
ID|NAME |EMAIL |CNT|
--|-----|---------------|---|
2|李四 |lisi@test.com | 2|
3|王五 |wangwu@test.com| 3|
4|李斯 |lisi@test.com | 2|
5|王五 |wangwu@test.com| 3|
6|王五 |wangwu@test.com| 3|
WITH d AS (
SELECT id, name, email,
count(*) over (partition by name, email) cnt
FROM people)
SELECT *
FROM d
WHERE cnt > 1
ORDER BY id;
ID|NAME |EMAIL |CNT|
--|-----|---------------|---|
3|王五 |wangwu@test.com| 3|
5|王五 |wangwu@test.com| 3|
6|王五 |wangwu@test.com| 3|
DELETE
FROM people
WHERE id NOT IN (
SELECT max(id)
FROM people
GROUP BY email
);
SELECT * FROM people;
ID|NAME |EMAIL |
--|-----|-----------------|
1|张三 |zhangsan@test.com|
4|李斯 |lisi@test.com |
6|王五 |wangwu@test.com |
DELETE
FROM people p
WHERE p.id NOT IN (
SELECT max(id)
FROM people
WHERE email = p.email
);
SELECT id, name, email,
row_number() over (PARTITION BY email ORDER BY id) AS row_num
FROM people;
ID|NAME|EMAIL |ROW_NUM|
--|----|------------------|-------|
2|李四 |lisi@test.com | 1|
4|李斯 |lisi@test.com | 2|
3|王五 |wangwu@test.com | 1|
5|王五 |wangwu@test.com | 2|
6|王五 |wangwu@test.com | 3|
1|张三 |zhangsan@test.com| 1|
DELETE
FROM people
WHERE id IN (
SELECT id
FROM (
SELECT id, name, email,
row_number() over (PARTITION BY email ORDER BY id DESC) AS row_num
FROM people) d
WHERE row_num > 1);
ALTER TABLE people ADD CONSTRAINT uk_people_email UNIQUE (email);
原文作者:SQL编程思想;如有侵权,请联系管理员删除。