代码之家  ›  专栏  ›  技术社区  ›  NoBullMan

SQL查询-删除列值重复的行

  •  2
  • NoBullMan  · 技术社区  · 6 年前

    我需要能够删除表中两列组合具有相同值的一些行。2018年,只有一个样本是9801-4805的组合。

    ID      CertID   DueDate
    676790  48983   2018-05-03
    678064  48983   2018-05-02
    678086  48983   2018-05-01
    678107  48983   2018-05-01
    678061  48983   2018-05-01
    

    我试图得到重复条目的列表,但得到的是整个表。这就是我使用的:

    WITH A   -- Get a list of unique combinations of ResponseDueDate and CertificateID
    AS  (
       SELECT Distinct
              ID,       
              ResponseDueDate,
              CertID
       FROM  FacCompliance
    )
    ,   B  -- Get a list of all those CertID values that have more than one ResponseDueDate associated
    AS  (
        SELECT CertID
        FROM   A
        GROUP BY
               CertID
        HAVING COUNT(*) > 1
    )
    SELECT  A.ID,
            A.ResponseDueDate,
            A.FacCertificateID
    FROM    A
        JOIN B
            ON  A.CertID = B.CertID
    order by CertID, ResponseDueDate;
    

    我使用的查询有什么问题,是否可以删除额外的行(在上面的示例中,保留(489832018-05-01)组合的一个实例,并删除其余的。我正在使用SQL Server 2016。

    2 回复  |  直到 6 年前
        1
  •  5
  •   avb    6 年前

    使用行号:

    WITH A AS  (
       SELECT 
              ID,       
              ResponseDueDate,
              CertID,
              ROW_NUMBER() over (partition by CertID, ResponseDueDate order by ResponseDueDate) lp
       FROM  FacCompliance
    )
    delete a
    where lp <> 1
    ;
    

    此外,如果 ID 独特,无需窗口功能即可完成:

    delete fc
    from  FacCompliance fc
    where exists (
        select 1
        from FacCompliance ref
        where ref.ResponseDueDate = fc.ResponseDueDate
            and ref.CertID = fc.CertID
            and ref.ID < fc.ID
    )
    
        2
  •  1
  •   UnhandledExcepSean    6 年前

    您可以按CertID和DueDate对数据进行排序,以消除多余的行。

    DECLARE @T TABLE (ID INT,CertID INT, DueDate DATE)
    INSERT INTO @T(ID,CertID,DueDate) SELECT 676790,48983,'2018-05-03'
    INSERT INTO @T(ID,CertID,DueDate) SELECT 678064,48983,'2018-05-02'
    INSERT INTO @T(ID,CertID,DueDate) SELECT 678086,48983,'2018-05-01'
    INSERT INTO @T(ID,CertID,DueDate) SELECT 678107,48983,'2018-05-01'
    INSERT INTO @T(ID,CertID,DueDate) SELECT 678061,48983,'2018-05-01'
    
    
    DELETE t
    FROM @T t
    INNER JOIN (
        SELECT
            *
            ,Row_number() OVER(PARTITION BY CertID,DueDate ORDER BY ID ASC) AS [Row]
        FROM @T
    ) Ordered ON Ordered.ID=t.ID
    WHERE [Row]<>1
    
    SELECT * FROM @T