Sql 简明教程

SQL - Handling Duplicates

有时,表或结果集包含重复记录。虽然在大多数情况下允许重复,但在某些情况下,有必要防止重复记录并从数据库表中删除它们。

Why is Handling Duplicates in SQL Necessary?

在 SQL 数据库中处理重复记录对于防止以下后果变得十分必要 -

  1. 组织数据库中存在重复记录会导致逻辑错误。

  2. 重复的数据占用存储空间,这导致数据库的使用效率降低。

  3. 由于资源使用增加,处理资源的总成本也会上升。

  4. 由于重复记录的存在导致逻辑错误增加,因此从数据库中数据分析得出的结论也会错误。

本章将介绍如何防止表中出现重复记录,以及如何删除已有的重复记录。

Preventing Duplicate Entries

为了防止重复记录进入表,我们可以在相关字段上定义一个主键或唯一索引。这些数据库约束确保指定列或列集中的每个条目是唯一的。

Example

让我们使用以下查询创建一个 CUSTOMERS 表 -

CREATE TABLE CUSTOMERS (
   FIRST_NAME CHAR(20),
   LAST_NAME CHAR(20),
   SEX CHAR(10)
);

由于我们没有在表上定义任何约束,因此可以向其中插入重复记录。为防止这种情况,在相关字段(比如 LAST_NAME 和 FIRST_NAME)上添加主键约束 -

ALTER TABLE CUSTOMERS
ADD PRIMARY KEY (LAST_NAME, FIRST_NAME);

Using INSERT IGNORE Query:

另外,我们可以使用 INSERT IGNORE 语句插入记录,而不为重复项生成错误,如下所示 -

INSERT IGNORE INTO CUSTOMERS (LAST_NAME, FIRST_NAME) VALUES
( 'Jay', 'Thomas'),
( 'Jay', 'Thomas');

正如您在下面看到的,该表将只包含一个记录(忽略重复值)。

FIRST_NAME

LAST_NAME

SEX

Thomas

Jay

NULL

Using REPLACE Query:

或者,使用 REPLACE 语句替换重复值,如下面的查询所示 -

REPLACE INTO CUSTOMERS (LAST_NAME, FIRST_NAME) VALUES
( 'Ajay', 'Kumar'),
( 'Ajay', 'Kumar');

该表将包含以下记录 -

FIRST_NAME

LAST_NAME

SEX

Kumar

Ajay

NULL

Thomas

Jay

NULL

应该根据所需的重复处理行为来选择 INSERT IGNORE 和 REPLACE 语句。INSERT IGNORE 语句保留第一组重复记录,并丢弃任何随后的重复项。相反,REPLACE 语句保留最后一组重复项,并擦除任何早期的重复项。

Using UNIQUE Constraint:

在表中强制体现唯一性的其他方法是添加 UNIQUE 约束,而不是 PRIMARY KEY 约束 −

CREATE TABLE BUYERS (
   FIRST_NAME CHAR(20) NOT NULL,
   LAST_NAME CHAR(20) NOT NULL,
   SEX CHAR(10),
   UNIQUE (LAST_NAME, FIRST_NAME)
);

Counting and Identifying Duplicates

要基于特定列计数和识别重复记录,我们可以使用 COUNT 函数和 GROUP BY 子句。

Example

以下是用于计算 BUYERS 中 FirstName 和 LastName 中重复记录的查询 −

SELECT COUNT(*) as repetitions, LAST_NAME, FIRST_NAME
FROM BUYERS
GROUP BY LAST_NAME, FIRST_NAME
HAVING repetitions > 1;

该查询将返回 PERSON_TABLE 表中所有重复记录的列表。要识别重复的值集,请按照以下步骤操作 −

  1. 确定包含可能重复值的列。

  2. 在列选择列表中列出这些列,以及 COUNT(*)。

  3. 还可在 GROUP BY 子句中列出列。

  4. 添加 HAVING 子句,通过要求组计数大于 1,消除唯一值。

Eliminating Duplicates from a Table

我们可以在 SELECT 语句中使用 DISTINCT 关键字,从表中检索唯一记录。

SELECT DISTINCT LAST_NAME, FIRST_NAME
FROM BUYERS
ORDER BY LAST_NAME;

或者,您可以包括一个 GROUP BY 子句,指定要选择以消除重复项的列 −

SELECT LAST_NAME, FIRST_NAME
FROM BUYERS
GROUP BY LAST_NAME, FIRST_NAME;