SQL-запрос - удалить строки с повторяющимся значением столбца - PullRequest
0 голосов
/ 18 мая 2018

Мне нужно иметь возможность удалить несколько строк в таблице, где комбинация из двух столбцов имеет одинаковое значение.Например, в приведенной ниже таблице примеров должна быть только одна комбинация (48983, 2018-05-01).

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;

Что не так с запросом, который я использую, и возможно ли удалить лишние строки (в приведенном выше примере сохраните один экземпляр (48983, 2018-05-01)сочетание и удалить остальное. Я использую SQL Server 2016.

Ответы [ 2 ]

0 голосов
/ 18 мая 2018

Вы можете заказать данные, разделенные по 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
0 голосов
/ 18 мая 2018

используйте номер строки:

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
)
...