http://community.csdn.net/Expert/topic/3566/3566321.xml?temp=.5448877回复人: dinya2003(OK) ( ) oracle为每个表的每一条记录都赋予了一个唯一的标识号rowid
它是伪列,在定义表结构时并不声明它,但是系统自动建立.
用desc查看的表结构的时候见看不到该字段.
用rowid来进行update,delete等操作时速度最快.
而且oracle7和oracle8及以后版的rowid不同:oracle 7 的rowid由三部分组成:
block.row.file
BBBBBBBB.RRRR.FFFF
文件块号.块中的行号.文件的绝对号oracle 8    8i       9i的rowid由四部分组成:
OOOOOOFFFBBBBBBRRR
OOOOOO:数据对象号,表示数据库段的编号
FFF表在空间中的相对文件号
BBBBBB:在一个文件中的块号
RRR块中行的位置号rowid数据类型的使用:
rowidtochar:把rowid转换成char类型.select rowidtochar(a.rowid) from testa a where rownum<=1
AABj3OAEoAAAHpjAAAselect chartorowid('AABj3OAEoAAAHpjAAA') from dual
AABj3OAEoAAAHpjAAA

解决方案 »

  1.   

    1. 保留tbname中以dm(在你的查询中应该是id,可能是你的笔误)分组的第一条记录,其余的删除。   因为a中有n条记录,故select 的结果集为n个一行记录的并集2. rowid是每行存储的逻辑地址,select min(rowid) no from tbname group by id 是取出tbname中以id分组的第一条记录的一个结果集。
      

  2.   

    1.说的通俗点就是:删除时,一条一条记录去找,当找到的记录dm值前面出现过,删除;
      dm值第一次出现,保留。所以得到1、2、5三条记录。
      

  3.   

    to   ORARichard(没钱的日子好难过啊)
    您解释的好像是第二个答案的内容是吧?
    把group by id改成group by dm就可以了吗?我直接用第二个应该一条不删除才对啊,但为什么敲上了
    error错误位于第一行,sql命令未正确结束啊???请您指教,谢谢了!!!
      

  4.   

    to   yxxx(小孬)
    答案一能给我详细解释一下吗?delete from tbname a where a.rowid>(select min(b.rowid) from tbname b where a.dm = b.dm);
    大于后面的句子,只能查出一个rowid,但好像应该能查处所有的第一次出现的dm的id才对啊,请给我解释一下,谢谢了!!
      

  5.   

    你的答案2从语法上就是错误的从严格意义上讲答案1也是不准确的,
    答案1正确的前提是你表的小id对应小的rowid。
    如果你理解了rowid和普通堆表的简单原理你就会明白,这种前提是有很多约束的。
    至少和你的表插入数据的顺序有关
    用以下SQL删除:
    delete from tbname a where a.id>(select min(b.id) from tbname b where a.dm = b.dm);
    效率不一定最高,但是可以保证其正确性。
      

  6.   

    我前面回答1,2分别对应两道题的。delete from tbname a,(select min(rowid) no from tbname group by id) b
    where a.rowid <> b.no;这句改一下delete tbname where rowid not in (select min(rowid) from tbname group by id);--是id还是dm自己定
      

  7.   

    to  zlindong(张林东) ( ) :
    ft,
    你认为min(b.rowid)会返回多个ROWID?是返回满足条件最小的
      

  8.   

    SQL> select * from tb1;       ID A
    --------- -
            1 a
            2 a
            3 b
            4 c
            5 aSQL> select rowid,tb1.* from tb1;ROWID                     ID A
    ------------------ --------- -
    AAAB1cAACAAAAgyAAA         1 a
    AAAB1cAACAAAAgyAAB         2 a
    AAAB1cAACAAAAgyAAC         3 b
    AAAB1cAACAAAAgyAAD         4 c
    AAAB1cAACAAAAgyAAE         5 aSQL> select min(rowid),a from tb1 group by a;MIN(ROWID)         A
    ------------------ -
    AAAB1cAACAAAAgyAAA a
    AAAB1cAACAAAAgyAAC b
    AAAB1cAACAAAAgyAAD cSQL> select * from tb1 where tb1.rowid>(select min(rowid) from tb1 tb2 where tb1.a=tb2.a);       ID A
    --------- -
            2 a
            5 a最后一句查询得到的结果就是要删除的记录。(这个例子可能能解决你对第一问的疑问)
      

  9.   

    to hippie1024(痞子):
    谢谢你的指正,请教一下,ORACLE中的delete from (). 这个()内是不是只能是一张表
      

  10.   

    不是,可以多张表,只要delete from 后面的句子在逻辑上是一个独立的VIEW就可以了
      

  11.   

    注意:
    是这样:
    Delete From (Select * From tb1 where tb1.x in (select x from tb2.y=tb1.y) )
    而不能这样哦:
    Delete From (Select * From tb1,tb2 where tb2.y=tb1.y) 其实好理解,第二个句子ORACLE是无法理解删除哪一个表的
      

  12.   

    select * from tb1 where tb1.rowid>(select min(rowid) from tb1 tb2 where tb1.a=tb2.a);
    其实和
    select *  from bbb a where a.rowid not in (select min(b.rowid) from bbb b group by dm);这条语句等效的
    rowid是按升序来的,其中select min(b.rowid) from bbb b group by dm这个语句,就是找到所有dm列中所有不重复记录的最小的rowid,这样解释应该明白吧
      

  13.   

    to hippie1024(痞子):
    谢谢  那ORACLE中好象也不支持
    delete tb1 from tb1,tb2,... where tb1.x=tb2.x and ...是吗?
      

  14.   

    oracle 不支持delete tb1 from tb1,tb2,... where tb1.x=tb2.x and ...oracle 中from 后是表示要删除的表,这和SQLSERVER里面是不一样的
      

  15.   

    谢谢大家了。最后想问一下,例子中的答案一
    delete from tbname a where a.rowid>(select min(b.rowid) from tbname b where a.dm = b.dm);
    大于号后面的最后返回不止一条记录,对吧????但是>号好像只能跟一行进行比较吧??请解释一下,谢谢了!!
      

  16.   

    你把delete from 换成select * from 就好理解了