从 SQL Server 表中查找和删除重复项

17 Mar 2025 | 6 分钟阅读

在 SQL Server 数据库中,表经常会包含重复或相同的数据。有时,为了减少整个数据库的冗余,需要从表中删除这些重复数据。因此,本文将介绍如何在 SQL Server 中查找和删除表中的重复行。

为了在 SQL Server 中查找和删除表中的重复行,我们需要遵循以下几个步骤:

  • 第一步是使用 GROUP BY 子句查找重复行,或者我们也可以使用 ROW_NUMBER() 函数。
  • 成功找到重复行后,下一步是使用 DELETE 语句删除这些重复行。

如上所述,第一步是识别或查找表中要删除的重复行。为此,我们需要执行一些操作,这些操作是:

  • 第一个操作或步骤是定义表中重复行的标准,这将区分该重复行与数据库中同一表中的其他行。
  • 现在,下一步是编写一个查询,该查询将使用我们在第一步中定义的标准来区分表中的重复行。

在本文中,我们将使用公共表表达式(Common Table Expression,简称 CTE)来查找表中的重复行。通过公共表表达式或 CTE,我们可以定义一个临时的命名结果集,该结果集在语句执行期间一直可用,并且该语句可以是 SELECT、INSERT、UPDATE、DELETE 或 MERGE 等任何语句。

SQL Server 中公共表表达式或 CTE 的语法是:

在上面写的语法中

  • Name_of_expression:name_of_expression 代表我们想要为公共表表达式或 CTE 指定的名称。然后,在 SQL 语句中引用此名称以使用此公共表表达式或 CTE。
  • Name_of_column:name_of_column 代表将定义公共表表达式或 CTE 的列。
  • definition_of_CTE:definition_of_CTE 代表编写公共表表达式或 CTE 实际定义的区域。
  • SQL_statement:SQL_statement 代表为其编写特定公共表表达式或 CTE 的 SQL 语句,并且该公共表表达式或 CTE 在此 SQL 语句(例如 SELECT、INSERT、UPDATE、DELETE 或 MERGE)的执行期间都有效。

因此,现在我们对公共表表达式或 CTE 有了初步的了解。我们将在本文后面部分继续讨论公共表表达式或 CTE。现在,让我们看看如何查找表中的重复行。为了理解公共表表达式或 CTE 的用法,并随后使用它来查找和删除表中的重复条目,我们将考虑一个示例。

让我们创建一个名为 students 的表,该表包含三个列:studID、rollno 和 Name,其数据类型分别为 varchar、int 和 varchar。使用 CREATE TABLE 命令创建具有上述架构的表的语法是:

输出

Find and Delete Duplicates From a Table in SQL Server

如图所示,我们已成功创建了一个具有上述架构的表,即三个列,其中两个数据类型为 varchar,一个为 int。

现在,让我们向 students 表添加一些数据。在 SQL Server 中使用 INSERT 命令向 students 表添加数据的语法是:

输出

studID     rollNo      Name                          
---------- ----------- ------------------------------
101              87459 Andrew 
102              54771 Samuel 
103              22100 Nirnay 
104              94365 Paul 
105              35479 Casey 
106              74000 Martin 
107              10211 Raphel 
105              35479 Casey 
103              22100 Nirnay 
101              87459 Andrew

正如我们所见,已成功向 students 表添加了十行数据,并且我们可以在 SELECT 查询的输出中看到这一点。

我们已成功创建表并向表中添加了数据。下一步是使用公共表表达式或 CTE 查找 students 表中的重复条目。因此,我们将创建一个公共表表达式或 CTE 来显示 students 表中存在的所有重复行。执行上述操作的公共表表达式或 CTE 的语法是:

输出

studID     rollNo      Name                          
---------- ----------- ------------------------------
101              87459 Andrew
101              87459 Andrew
103              22100 Nirnay
103              22100 Nirnay
105              35479 Casey
105              35479 Casey

在上面编写的查询中,我们创建了一个名为 dup_cte 的公共表表达式或 CTE,它使用 COUNT() 函数计算 students 表中每一行的出现次数,并且仅返回表中计数大于一的那些行,或者我们也可以说只返回重复行或在表中出现多次的行。然后,公共表表达式或 CTE 提供的重复行数据被用于 SELECT 命令,以显示 students 表中的所有重复行。然后,在 students 表和由 dup_cte 的公共表表达式或 CTE 提供的行之间应用 INNER JOIN。最后的结果使用公共表表达式或 CTE 的 SQL 命令部分中的 SELECT 命令显示。我们可以使用除 SELECT 命令以外的任何命令来根据我们的需要在此公共表表达式或 CTE 的 SQL 命令部分中删除或更新数据。

现在我们已经成功识别或找到了表中要删除的重复行,下一步是从表中删除这些重复行。使用公共表表达式从 students 表中删除重复行的语法是:

输出

studID     rollNo      Name                          
---------- ----------- ------------------------------
101              87459 Andrew
102              54771 Samuel
103              22100 Nirnay
104              94365 Paul
105              35479 Casey
106              74000 Martin
107              10211 Raphel

正如我们在上面查询的输出中所看到的,student 表中的所有重复行都已成功删除。在此查询中,我们使用了 ROW_NUMBER() 函数而不是 COUNT() 函数来获取 students 表中的重复行。使用 ROW_NUMBER() 函数的公共表表达式产生了名为 dup_cte 的公共表表达式或 CTE 的输出结果。

studID     rollNo      Name                           row_num             
---------- ----------- ------------------------------ --------------------
101              87459 Andrew                                            	1
101              87459 Andrew                                            	2
102              54771 Samuel                                            	1
103              22100 Nirnay                                            	1
103              22100 Nirnay                                            	2
104              94365 Paul                                              	1
105              35479 Casey                                             	1
105              35479 Casey                                             	2
106              74000 Martin                                            	1
107              10211 Raphel                                            	1

如上输出所示,每行在 row_num 列下显示其出现次数或行号。因此,我们使用了名为 dup_cte 的公共表表达式生成的输出,并且仅删除了 row_num 大于一的那些行。因此,仅删除表中出现多次的那些行。从而从表中删除了重复行。

因此,通过本文,我们能够使用公共表表达式或 CTE、COUNT() 函数和 ROW_COUNT() 函数成功地在 SQL Server 中查找和删除表中的重复项。