日期:2014-05-16  浏览次数:20668 次

Oracle 中对clob字段进行distinct 操作
oracle 10+g不支持对类型为CLOB的列进行distinct,也不支持union,所以在遇到此问题,需要对SQL语句进行重新,从另一思想去实现同样的效果的。union没仔细思考过,具体还要看union里面的条件如何,最简单的方法是利用to_char将clob字段转换成char型,但存在一个问题,如clob中的字符长度超过4000时会报错。在此主要对distinct的转换方法进行列举:

表结构如下:

Table1:


id(varchar)  title(varchar)  content(clob)
1  title1  <CLOB>
2  title2  <CLOB>


Table2:


id(varchar)  table_id(varchar)  object(varchar)
1  1  123
2  1  abc
3  1  111
4  1  222
5  2  123




SQL语句:

select distinct table1.* from table2 table2 left join table1 table1 on table1.id = talbe2.table_id

where table2.object = '123' or table2.object = '111' or table2.object = '222' or table2.object = '333'

执行该语句,出现错误:ORA-00932,数据类型不一致:应为-,却获得CLOB。




1、利用rowid,过滤重复的数据。

这个方法的思路来源,就是对某个字段进行distinct时的解决方法。

基本思路:select   B.name,B.id   from   table   B   where     not   exists   (select   1   from   table   A     where   A.name   =   B.name   AND   B.id_key   >   A.id_key)

A表,B表为同一张表,表中的数据存在name相同的,但id_key不同,该语句的目的是把同名的只显示一条即可,其它同名记录过滤。

将该思想转换到当前的问题上,利用每条记录的rowid不同进行过滤。

select p4.*, p4.rowid from (
select p.* from table2 s left join table1 p on s.table_id = p.id
where s1.object = '123' or s1.object = '111' or s1.object = '222' or s1.object = '333'
) p4
where not exists (
select 1, p2.rowid from (
select p1.* from table2 s1 left join table1 p1 on s1.table_id= p1.id
where s1.object = '123' or s1.object = '111' or s1.object = '222' or s1.object = '333') p2
where p4.id = p2.id and p4.rowid > p2.rowid
)

2、采用子查询进行过滤重复的数据。

select * from table1 t1 where t1.id in (

selcet distinct p1.id from table2 s1 left join table1 p1 on s1.table_id= p1.id
      where s1.object = '123' or s1.object = '111' or s1.object = '222' or s1.object = '333'

)

3、采用to_char函数,直接使用distinct(前提是:clob字段中的字符长度少于4000)。

select distinct table1.id, table1.tittle, to_char(table1.content) from table2 table2

        left join table1 table1 on table1.id =  talbe2.table_id

        where table2.object = '123' or table2.object = '111' or table2.object = '222' or table2.object = '333'