oracle 根据字段范围扩展成多行

需求:

现在有两个表,一个是票号区间段

一个是单个票号

然后怎么找出区间段多出的票号

比如 区间段是1-10

然后现在另一张表的票是

1,2,4,5,6

然后结果是3,7,8,9

分析:

是把1-10范围的值,变成10行,每行是1到9,然后和票据编码关联,关联不上的就是没用过的

主要是这个一行根据字段的范围扩成多行

oracle 根据字段范围扩展成多行_第1张图片

oracle 根据字段范围扩展成多行_第2张图片

oracle 根据字段范围扩展成多行_第3张图片

create table j (id number,one number,two number);

select * from j for update;

create table j2 (id number,one number);

select * from j2 for update;

with temp1 as(

select distinct * from (

select distinct j.*,level as k,level+one-1 as ne from j /*where j.id=2*/  connect by level<= j.two -j.one+1

)

)

select temp1.id,temp1.one,temp1.two,temp1.ne from temp1

left join j2

on j2.id=temp1.id and j2.one=temp1.ne

where j2.one is null

order by temp1.id, temp1.ne

有个问题with子句里面

select distinct j.*,level as k,level+one-1 as ne from j /*where j.id=2*/  connect by level<= j.two -j.one+1

会出现大量重复数据,2行会变成3000行,有跑蹦数据库的风险,

改良如下

加两个  j.ID=PRIOR j.ID    PRIOR SYS_GUID() IS NOT NULL 就不会重复了 ,connect by level涉及到父级子级的问题,比如原表两条数据的时候,先connect by level < 10后,两条变成20条,这20条相互乱认父级,就会导致大量数据重复,类似笛卡尔积,如果找不到父级子级,就把每条数据当成子级或者父级,就一直循环重复了,当然原表只有一条数据就不会重复了,如图,每行数据会乱认父级

oracle 根据字段范围扩展成多行_第4张图片

改成:

select  j.*,level as k,level+one-1 as ne from(select j.* from  j /*where j.id in(2)*/ ) j   connect by j.ID=PRIOR j.ID

and level<= j.two -j.one+1 and  PRIOR SYS_GUID() IS NOT NULL)

oracle 根据字段范围扩展成多行_第5张图片

最终:

with temp1 as(

select distinct * from (

select  j.*,level as k,level+one-1 as ne from(select j.* from  j /*where j.id in(2)*/ ) j   connect by j.ID=PRIOR j.ID

and level<= j.two -j.one+1 and  PRIOR SYS_GUID() IS NOT NULL)

)

select temp1.id,temp1.one,temp1.two,temp1.ne from temp1

left join j2

on j2.id=temp1.id and j2.one=temp1.ne

where j2.one is null

order by temp1.id, temp1.ne

oracle 根据字段范围扩展成多行_第6张图片

小记:

select  j.*,level as k,level+one-1 as ne from(select j.* from  j /*where j.id in(2)*/ ) j  where  j.id in(2)

  connect by /*j.ID=PRIOR j.ID

and*/ level<= j.two -j.one+1 --and  PRIOR SYS_GUID() IS NOT NULL

select  j.*,level as k,level+one-1 as ne from(select j.* from  j where j.id in(2) ) j    connect by /*j.ID=PRIOR j.ID

and*/ level<= j.two -j.one+1 --and  PRIOR SYS_GUID() IS NOT NULL

这两个有区别,一个是connect by 后过滤,会有大量重复数据,一个是之前就过滤,没重复数据,重复数据是因为每行数据乱认父级,解决办法就是加加两个  j.ID=PRIOR j.ID    PRIOR SYS_GUID() IS NOT NULL 就不会重复了

你可能感兴趣的:(oracle)