[英]Conditional delete in oracle using sql or plsql
We have an oracle table x and we have values in it in a following manner 我们有一个oracle表x,并以下面的方式在其中包含值
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. 现在,我必须使用num1,dt从此表中删除重复数据,如果num1和dt的值不是4,则应存在于表中,并且应该删除cd = 4。 Here in below condition 3 or any other value should exist but it should not be 4
在下面的条件3中,应该存在任何其他值,但不应为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. 现在,此处4应该在2,24/06/2017中被完全删除,并且表中每个字段仅应存在1行,即:2 24/06/2017 1和2 24/06/2017 2应该存在。
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. 现在在第三种情况下,如果num1和date除了4以外没有其他值,则这些日期应该只有4的1行。
3 26-06-2017 4
3 26-06-2017 4
Please provide solution for this, help will be appreciated. 请为此提供解决方案,我们将不胜感激。
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))
Oracle conveniently has rowid
, which can really help with this. Oracle方便地具有
rowid
,它可以真正帮助您。 Here is an approach that uses rowid
: 这是一种使用
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. 每个
num1
/ date
比较将只保留一行。
If you are using Oracle 12C+, then a more intuitive form of this query is: 如果使用的是Oracle 12C +,则此查询的更直观形式为:
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. 这在早期版本中不起作用,因为获取一行需要附加的子查询-且该子查询无法与外部查询相关联。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.