📜  从表中删除重复行的查询 - SQL (1)

📅  最后修改于: 2023-12-03 15:06:38.694000             🧑  作者: Mango

从表中删除重复行的查询 - SQL

在处理数据库时,我们有时会遇到需要从表中删除重复行的情况。SQL提供了几种方法来实现这个目的。

方法一:使用DISTINCT关键字

使用DISTINCT关键字可以返回唯一的行,从而避免重复行的问题。这种方法适用于只有部分列有重复值的情况。

例如,假设我们有一个名为customers的表,其中包含以下列:idnameemail。如果我们想要删除重复的nameemail组合,可以使用以下SQL查询:

DELETE FROM customers
WHERE id NOT IN (
   SELECT MIN(id)
   FROM customers
   GROUP BY name, email);

上述查询使用子查询和GROUP BY语句查找具有重复nameemail的行,然后使用DELETE语句删除除了具有最小id值的行之外的行。

方法二:使用ROW_NUMBER()函数

ROW_NUMBER()函数可以为查询结果中的每一行分配一个唯一的序号。这种方法可以更灵活地处理重复行的情况。

例如,使用上述customers表,如果我们想要删除具有重复nameemail组合的行,可以使用以下SQL查询:

WITH cte AS (
   SELECT ROW_NUMBER() OVER(
      PARTITION BY name, email ORDER BY id) AS rownum
   FROM customers)
DELETE FROM cte WHERE rownum > 1;

上述查询使用了CTE(公用表表达式)和ROW_NUMBER()函数来为具有重复nameemail组合的行分配一个唯一的序号,并使用DELETE语句删除具有序号大于1的行。

方法三:使用临时表

如果表中包含大量重复行,使用临时表可能是更高效的方法。

例如,假设我们有一个名为sales的表,其中包含以下列:idorder_numbercustomer_nameorder_total。我们想要删除具有相同order_numbercustomer_name的行,但保留具有最大order_total值的行。可以使用以下SQL查询:

CREATE TABLE #temp_sales (
   id INT PRIMARY KEY,
   order_number VARCHAR(20),
   customer_name VARCHAR(50),
   order_total MONEY);

INSERT INTO #temp_sales (id, order_number, customer_name, order_total)
SELECT id, order_number, customer_name, order_total
FROM sales;

DELETE FROM sales;

INSERT INTO sales (id, order_number, customer_name, order_total)
SELECT t.id, t.order_number, t.customer_name, t.order_total
FROM (
   SELECT id, order_number, customer_name, order_total,
          ROW_NUMBER() OVER(
             PARTITION BY order_number, customer_name
             ORDER BY order_total DESC) AS rownum
   FROM #temp_sales) t
WHERE t.rownum = 1;

DROP TABLE #temp_sales;

上述查询使用了临时表和ROW_NUMBER()函数来查找具有相同order_numbercustomer_name的行,然后使用DELETE语句删除数量多于1的行,并使用INSERT语句将具有最大order_total值的行重新插入sales表中。

总之,在SQL中有多种方法可以从表中删除重复行,可以根据具体情况选择最合适的方法。