【问题标题】:Delete where one column contains duplicates删除一列包含重复项的位置
【发布时间】:2013-02-15 00:55:04
【问题描述】:

考虑以下:

ProductID  Supplier
---------  --------
111        Microsoft
112        Microsoft
222        Apple Mac
222        Apple
223        Apple

在此示例中,产品 222 被重复,因为供应商在提供的数据中被称为两个名称。

我有成千上万种产品的此类数据。如何删除重复的产品或选择单个结果 - 例如使用 SELECT TOP 1 进行自我加入或类似的东西?

谢谢!

【问题讨论】:

  • 什么版本的 SQL Server?
  • 你可以用一个 DELETE 来完成。只有一件事,先备份它。

标签: sql sql-server tsql sql-delete


【解决方案1】:

我认为你想做以下事情:

select t.*
from (select t.*,
             row_number() over (partition by product_id order by (select NULL)) as seqnum
      from t
     ) t
where seqnum = 1

这会为每个产品选择任意一行。

要删除除一个以外的所有行,您可以使用相同的想法:

with todelete (
      (select t.*,
               row_number() over (partition by product_id order by (select NULL)) as seqnum
        from t
      )
delete from to_delete where seqnum > 1

【讨论】:

  • Gordon,您的选择声明完全符合我的需要 - 谢谢。有没有办法使用组的 max seqnum 来有效地得到最新的结果?再次感谢!
【解决方案2】:
DELETE  a
FROM    tableName a
        LEFT JOIN
        (
            SELECT  Supplier, MIN(ProductID) min_ID
            FROM    tableName
            GROUP   BY Supplier
        ) b ON  a.supplier = b.supplier AND
                a.ProductID = b.min_ID
WHERE   b.Supplier IS NULL

或者如果你想删除拥有超过onbe产品的productID

WITH cte 
AS
(
    SELECT  ProductID, Supplier,
            ROW_NUMBER() OVER (PARTITION BY ProductID ORDER BY Supplier) rn
    FROM    tableName
)
DELETE FROM cte WHERE rn > 1

【讨论】:

    【解决方案3】:
    ;WITH Products_CTE AS
        (
        SELECT ProductID, Supplier,
            ROW_NUMBER() OVER (PARTITION BY ProductID ORDER BY <some value>) as rn
        FROM PRODUCTS
        )
    
    SELECT *
    FROM Products_CTE
    WHERE rn = 1
    

    some value 将成为决定您保留哪个供应商版本的关键。如果您想要供应商的第一个实例,您可以使用 DateAdded 列(如果存在)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-13
      • 2019-09-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多