2017-06-21 77 views
0

我想根据条件从表中删除重复的行。根据Oracle中的条件删除重复行

例如, 表ABC:

ID Name Pin Status 
111 Pope 909 New 
222 Jazz 909 New 
333 Volk 767 Assigned 
444 Audi 767 New 
555 Pink 435 New 

我想删除它具有以下条件的基础上同“针”重复记录:

  1. 如果两个相同的PIN记录有新的状态 - 删除其中的任何一个。
  2. 如果其中一个Pin记录的状态为New,另一个记录的状态为已分配 - 删除'New'状态记录。

我写了下面的SQL,但我想知道是否有更好的方法来处理这个使用PK。

为1:

DELETE FROM ABC WHERE ID IN (
SELECT 
    a.id 
FROM ABC a 
WHERE a.rowid < 
    (SELECT max(rowid) 
    FROM ABC b 
    WHERE b.pin = a.pin 
    AND a.status = b.status 
    AND b.status in ('New') 
) 
); 

为2:

DELETE FROM ABC WHERE ID IN (
SELECT 
    a.id 
FROM ABC a 
WHERE a.rowid < 
    (SELECT max(rowid) 
    FROM ABC b 
    WHERE b.pin = a.pin 
    AND a.status <> b.status 
    AND a.status in ('New') 
    AND b.status in ('Assigned') 
) 
); 
+0

如果哪一个引脚分配多个和多种新行? –

+0

如果两行都具有与分配状态相同的引脚 - 什么也不做。 – Murali

回答

0

你可以试试这个。

--Query 1: 
DELETE FROM ABC 
WHERE ID NOT IN (SELECT MIN(ID) 
       FROM ABC 
       GROUP BY Pin 
       HAVING COUNT(*)=COUNT(CASE WHEN status = 'New' THEN 1 END) 
       ); 

--Query 2: 
DELETE FROM ABC 
WHERE ID IN (SELECT ID 
      FROM ABC A 
      WHERE status = 'New' 
      AND EXISTS (SELECT 1 FROM ABC B 
         WHERE A.Pin=B.Pin AND B.status='Assigned') 

      ); 
0

如果至多有两个记录每个pin

DELETE FROM ABC 
WHERE rowid IN (SELECT MIN(CASE WHEN a.status = 'NEW' then rowid END) 
       FROM ABC a 
       WHERE abc.pin = a.pin AND 
         a.status IN ('New', 'Assigned' 
       GROUP BY a.pin 
       HAVING COUNT(*) > 1 
       ); 
0

试试这个Query--

-- Select ID, Name, Pin, Status 
Delete 
From (
    Select 
     ID, Name, Pin, Status, 
     Row_Number() Over(Partition By Pin Order By Pin) As PinRowNum, 
     Row_Number() Over(Partition By Pin, Status Order By Status) As 
    StatusRowNum 
From ABC 
) As D Where StatusRowNum > 1 Or (PinRowNum > 1 And StatusRowNum = 1)