是否删除SQL Server中的重复行?

是否删除SQL Server中的重复行?,sql,sql-server,duplicates,common-table-expression,Sql,Sql Server,Duplicates,Common Table Expression,我有一个SQL Server 2017表,其中包含包含重复行的销售数据,例如: +---------+---------+---------+----------+---------+----------+ | year_id | week_id | good_id | store_id | ship_id | quantity | +---------+---------+---------+----------+---------+----------+ | 2017 | 43

我有一个SQL Server 2017表,其中包含包含重复行的销售数据,例如:

+---------+---------+---------+----------+---------+----------+
| year_id | week_id | good_id | store_id | ship_id | quantity |
+---------+---------+---------+----------+---------+----------+
| 2017    | 43      | 154876  | 19       | 6       | 2        |
+---------+---------+---------+----------+---------+----------+
| 2017    | 43      | 154876  | 19       | 6       | 0        |
+---------+---------+---------+----------+---------+----------+
| 2019    | 32      | 456123  | 67       | 4       | 6        |
+---------+---------+---------+----------+---------+----------+
| 2019    | 32      | 456123  | 67       | 4       | 4        |
+---------+---------+---------+----------+---------+----------+
| 2019    | 32      | 456123  | 67       | 4       | 0        |
+---------+---------+---------+----------+---------+----------+
| 2018    | 32      | 456123  | 67       | 4       | 0        |
+---------+---------+---------+----------+---------+----------+
+---------+---------+---------+----------+---------+----------+
| year_id | week_id | good_id | store_id | ship_id | quantity |
+---------+---------+---------+----------+---------+----------+
| 2017    | 43      | 154876  | 19       | 6       | 2        |
+---------+---------+---------+----------+---------+----------+
| 2019    | 32      | 456123  | 67       | 4       | 6        |
+---------+---------+---------+----------+---------+----------+
我想删除具有相同年份标识、周标识、良好标识、存储标识和发货标识列的行,但数量为0。例如:

+---------+---------+---------+----------+---------+----------+
| year_id | week_id | good_id | store_id | ship_id | quantity |
+---------+---------+---------+----------+---------+----------+
| 2017    | 43      | 154876  | 19       | 6       | 2        |
+---------+---------+---------+----------+---------+----------+
| 2017    | 43      | 154876  | 19       | 6       | 0        |
+---------+---------+---------+----------+---------+----------+
| 2019    | 32      | 456123  | 67       | 4       | 6        |
+---------+---------+---------+----------+---------+----------+
| 2019    | 32      | 456123  | 67       | 4       | 4        |
+---------+---------+---------+----------+---------+----------+
| 2019    | 32      | 456123  | 67       | 4       | 0        |
+---------+---------+---------+----------+---------+----------+
| 2018    | 32      | 456123  | 67       | 4       | 0        |
+---------+---------+---------+----------+---------+----------+
+---------+---------+---------+----------+---------+----------+
| year_id | week_id | good_id | store_id | ship_id | quantity |
+---------+---------+---------+----------+---------+----------+
| 2017    | 43      | 154876  | 19       | 6       | 2        |
+---------+---------+---------+----------+---------+----------+
| 2019    | 32      | 456123  | 67       | 4       | 6        |
+---------+---------+---------+----------+---------+----------+
我找到了一个可以执行此操作的查询,但我不知道如何指示需要删除数量等于0的行

WITH CTE AS(
   SELECT year_id, week_id, good_id, store_id, ship_id,
       RN = ROW_NUMBER()OVER(PARTITION BY year_id ORDER BY year_id)
   FROM dbo.sales
)
DELETE FROM CTE WHERE RN > 1

在您的情况下,查询将如下所示

 WITH CTE AS(
       SELECT year_id, week_id, good_id, store_id, ship_id,
           RN = ROW_NUMBER()OVER(PARTITION BY year_id, week_id, good_id, store_id, ship_id ORDER BY quantity)
, count(*) as cnt
       FROM dbo.sales group by year_id, week_id, good_id, store_id, ship_id
    )
    DELETE FROM CTE WHERE RN = 1 and quantity=0 and cnt>1

如果只想复制quantity=0,则需要where条件中的quantity=0,否则可以从where删除该条件,因为可删除的CTE位于正确的轨道上。这里有一个方法:

WITH cte AS (
    SELECT *, COUNT(*) OVER (PARTITION BY year_id, week_id, good_id, store_id, ship_id) cnt
    FROM dbo.sales
)

DELETE
FROM cte
WHERE cnt = 2 AND quantity = 0;
这将删除与您提到的五列相关且数量为零的所有重复记录。如果您想同时满足多于一对的副本,只需更改cnt上的限制。

,将CTE作为 选择年份标识、周标识、良好标识、门店标识、发货标识、数量、, 按年度id、周id、良好id、门店id、发货id订单划分的分区行数 按数量说明 来自dbo.sales
从CTE中删除,其中RN>1且数量=0

请根据我更新的输入更新您的输出。@GuidoG opps另一个条件need@TimBiegeleisen我使用了分组方式,可能是您没有注意到cnt>=2?可能存在不止一个副本。@Serg我在回答中对此提出了警告。OP给出的样本数据只显示了成对的重复项,所以我迎合了我的答案。