删除前面的记录,保留最近50条
delete  from (select * from tab order by time asc) where rownum<= ((select max(rownum) from tab )-50)
为什么这样写,得不到想要的结果呢?

解决方案 »

  1.   

    试一下这样写.
    delete from 
    (select * from Tb order by time asc) where rownum<max(rownum))
    where rownum>50;可能是你的where 条件写错了
      

  2.   

    不好意思,写错了,应该是Tab:
    delete   from   
    (select   *   from   Tab   order   by   time   asc)   where   rownum <max(rownum)) 
    where   rownum> 50; 
      

  3.   

    rownum>50,应该不能这样写吧!
    delete from必须跟具体表,不能跟子查询。否则会报ora-01732错误。
    delete from tab where rownum < ((select count(*) from tab)-49)
      

  4.   

    1.要明确delete后面必须跟具体的表,不能采用楼主所用的子查询的结果。
    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条纪录即可。
      

  5.   

    thank you very much!!!!!!!!!!!!!!!!!
      

  6.   

    [thank   you   very   much!!!!!!!!!!!!!!!!!]
    别忘了给分哈:)