删除MariaDB中重复行的2种方法(忽略主键)
以下是当 MariaDB 中的表具有主键或唯一标识符列时从这些行中删除重复行的示例。
这些示例删除重复行,但保留一行。因此,在两行相同的情况下,它会删除其中一行并保留另一行。
示例数据
我们的示例使用以下数据:
SELECT * FROM Dogs;
结果:
+——-+———–+———-+ | DogId | FirstName | LastName | +——-+———–+———-+ | 1 | Bark | Smith | | 2 | Bark | Smith | | 3 | Woof | Jones | | 4 | Ruff | Robinson | | 5 | Wag | Johnson | | 6 | Wag | Johnson | | 7 | Wag | Johnson | +——-+———–+———-+
我们可以看到前两行是重复的,最后三行也是重复的。
Thecolumn 保存唯一值(因为它是表的主键),因此,严格来说,没有重复项。但在实际情况下,您经常需要对包含主键的表进行重复数据消除。因此,在本文中,我们忽略主键,并在其余列中检测重复值。DogId
选项 1
让我们通过选择将删除的所有行来开始第一个选项:
SELECT * FROM Dogs
WHERE DogId IN (
SELECT DogId FROM Dogs
EXCEPT SELECT MIN(DogId) FROM Dogs
GROUP BY FirstName, LastName
);
结果:
+——-+———–+———-+ | DogId | FirstName | LastName | +——-+———–+———-+ | 2 | Bark | Smith | | 6 | Wag | Johnson | | 7 | Wag | Johnson | +——-+———–+———-+
要删除这些重复的行,我们可以切换到:SELECT *``DELETE
DELETE FROM Dogs
WHERE DogId IN (
SELECT DogId FROM Dogs
EXCEPT SELECT MIN(DogId) FROM Dogs
GROUP BY FirstName, LastName
);
结果:
Query OK, 3 rows affected (0.017 sec)
为了验证结果,我们可以选择表中所有剩余的行:
SELECT * FROM Dogs;
结果:
+——-+———–+———-+ | DogId | FirstName | LastName | +——-+———–+———-+ | 1 | Bark | Smith | | 3 | Woof | Jones | | 4 | Ruff | Robinson | | 5 | Wag | Johnson | +——-+———–+———-+
我们也可以使用函数而不是函数来更改删除哪些行。MAX()``MIN()
选项 2
在此示例中,我们假设表已还原到其原始状态(包含重复项)。
我们可以使用以下查询来检查重复的行:
SELECT *
FROM Dogs d1, Dogs d2
WHERE d1.FirstName = d2.FirstName
AND d1.LastName = d2.LastName
AND d1.DogId <> d2.DogId
AND d1.DogId = (
SELECT MAX(DogId)
FROM Dogs d3
WHERE d3.FirstName = d1.FirstName
AND d3.LastName = d1.LastName
);
结果:
+——-+———–+———-+——-+———–+———-+ | DogId | FirstName | LastName | DogId | FirstName | LastName | +——-+———–+———-+——-+———–+———-+ | 2 | Bark | Smith | 1 | Bark | Smith | | 7 | Wag | Johnson | 5 | Wag | Johnson | | 7 | Wag | Johnson | 6 | Wag | Johnson | +——-+———–+———-+——-+———–+———-+
我们可以修改该查询以删除重复项:
DELETE FROM Dogs WHERE DogId IN (
SELECT d2.DogId
FROM Dogs d1, Dogs d2
WHERE d1.FirstName = d2.FirstName
AND d1.LastName = d2.LastName
AND d1.DogId <> d2.DogId
AND d1.DogId=(
SELECT MIN(DogId)
FROM Dogs d3
WHERE d3.FirstName = d1.FirstName
AND d3.LastName = d1.LastName
)
);
结果:
Query OK, 3 rows affected (0.075 sec)
该表现已消除重复数据。
我们可以通过再次选择所有行来验证这一点:
SELECT * FROM Dogs;
结果:
+——-+———–+———-+ | DogId | FirstName | LastName | +——-+———–+———-+ | 1 | Bark | Smith | | 3 | Woof | Jones | | 4 | Ruff | Robinson | | 5 | Wag | Johnson | +——-+———–+———-+
如果愿意,我们可以使用而不是从重复项中删除其他行。MAX()``MIN()