删除前面的记录,保留最近50条
delete from (select * from tab order by time asc) where rownum<= ((select max(rownum) from tab )-50)
为什么这样写,得不到想要的结果呢?
delete from (select * from tab order by time asc) where rownum<= ((select max(rownum) from tab )-50)
为什么这样写,得不到想要的结果呢?
delete from
(select * from Tb order by time asc) where rownum<max(rownum))
where rownum>50;可能是你的where 条件写错了
delete from
(select * from Tab order by time asc) where rownum <max(rownum))
where rownum> 50;
delete from必须跟具体表,不能跟子查询。否则会报ora-01732错误。
delete from tab where rownum < ((select count(*) from tab)-49)
2.既然delete后面必须跟具体的表,同时又要根据time排序来判断“最近的50条”,所以这问题用rownum解决不了。
可以采用以下两种方式之一:
1)找出以time排序的倒数第50条对应的time(设为neededTime),然后delete from tab where
time<neededTime。这样问题就集中于怎么找到neededTime(这并不困难,但要注意tab表纪录不足50条的
情况),这种方式的缺点是可能留下的不是正好50条,因为time=neededTime的纪录可能不只一条(举例来
说:有49条纪录的time是10:00,3条纪录的time是09:00,其余纪录的时间都小于09:00,那么neededTime
肯定为09:00,而这时候采用delete from tab where time<neededTime则留下的纪录是52条),这种问题
是否可以通过业务来避免,就要看楼主实际业务了。
2)找出以time排序的倒数50条各条纪录的rowid(显然是个集合,或者找到主键集合也可以),然后
delete from tab where rowid not in(前面查询出来的rowid集合),这种方式肯定会只留下50条纪录,
SQL语句也不是太复杂,但同样要注意tab表纪录不足50条的情况,SQL代码如下
delete from tab where rowid not in (--如果tab表纪录不是远大于50条的话,可以用in的方式
select rd from
(select rownum rn,rowid rd from
(select rowid from tab order by time asc))
where rn<(select count(*) from tab)-49)
and (select count(*) from tab)>50 --tab表纪录小于50条时则不删除
此方法的缺点是性能有比较大的损耗,为提高性能可以引入PL/SQL,对tab表作一次循环找到倒数50条纪录即可。
别忘了给分哈:)