Reputation: 33
We have an oracle table x and we have values in it in a following manner
num1 dt cd
1 24-06-2017 3
1 24-06-2017 4
2 24-06-2017 1
2 24-06-2017 2
2 24-06-2017 4
2 25-06-2017 3
2 25-06-2017 4
Now I have to delete duplicate data from this table using num1,dt , if num1 and dt have any other value instead of 4 then it should exist in table and cd=4 should be deleted. Here in below condition 3 or any other value should exist but it should not be 4
1 24-06-2017 3
1 24-06-2017 4
Now here 4 should be deleted completely for 2 , 24/06/2017 and only 1 rows of each field should exist in the table ie :2 24/06/2017 1 and 2 24/06/2017 2 should exist.
2 24-06-2017 1
2 24-06-2017 2
2 24-06-2017 4
Now in third case if we dont have any other value except 4 for num1 and date then we should have only 1 row of 4 for these dates.
3 26-06-2017 4
3 26-06-2017 4
Please provide solution for this, help will be appreciated.
Upvotes: 2
Views: 3012
Reputation: 1271141
Oracle conveniently has rowid
, which can really help with this. Here is an approach that uses rowid
:
delete from t
where t.rowid <> (select max(rowid) keep (dense_rank first
order by (case when cd = 4 then 2 else 1 end)
)
from t
where t2.num1 = t.num1 and t2.date = t.date
);
This will keep exactly one row per num1
/date
comparison.
If you are using Oracle 12C+, then a more intuitive form of this query is:
delete from t
where t.rowid <> (select rowid
from t
where t2.num1 = t.num1 and t2.date = t.date
order by (case when cd = 4 then 2 else 1 end)
fetch first 1 row only
);
This doesn't work in earlier versions because fetching one row requires an additional subquery -- and that subquery cannot be correlated with the outer query.
Upvotes: 2
Reputation: 2191
If I get your question right it might work like this:
DELETE FROM table
WHERE (num1, dt, ct) IN (SELECT num1, dt, 4
FROM table
GROUP BY num1, dt
HAVING MAX(ct) != 4
OR MIN(ct) != 4)
OR ((num, dt, ct) IN (SELECT num1, dt, MAX(ct)
FROM table
GROUP BY num1, dt
HAVING MAX(ct) = 4
AND MIN(ct) = 4)
AND rowid NOT IN (SELECT MIN(rowid)
FROM table
GROUP BY num1, dt
HAVING MAX(ct) = 4
AND MIN(ct) = 4))
Upvotes: 2