我想实现的是在一个表a1中的数据段中所以数据是否全部分散在另一个表中a2
例如:
a1表中:字段名  : id        kssj(开始数据)        jssj(结束数据)
                    1        1000                     2000
                    2        2500                     3000
a2表中:字段名  : id       kssj2(开始数据)        jssj2(结束数据)
                    1        1000                     1500
                    2        1510                     2510
                    3        2511                     2900

解决方案 »

  1.   

    我的想法是做个函数判断:
    对于a1表中的每一条记录循环,
      select max(jssj2) into vintI from a2 where kssj2<=kssj 
      如果无记录,直接返回false
      如果有记录,判断是否vintI>=jssj,
        如果vintI>=jssj,循环a1表中下一条记录
        如果vintI<jssj,以kssj2<=vintI为条件重复上面操作。
    a1表中的所有记录都循环结束,返回true有个前提,结束数据一定要大于开始数据,如果有相等的情况就会出现死循环了
    为了提高效率,可以事先将a1,a2表整理一下,使每个表中的数据不存在交集
      

  2.   

    如果a1,a2表本身的数据就不存在交集,那就好办了
    select (select count(*) from a1)-(select count(*) from (select distinct a1.id from a1,a2 where a1.kssj>=a2.kssj2 and a1.jssj<=a2.jssj2)) from dual
    判断一下,大于零就不满足,等于零就满足
      

  3.   

    如果不存在交集,直接这样不就是符合条件的数据吗?select a2.* from a2,a1
    where a2.KSSJ2>a1.KSSJ
    and  a2.JSSJ2>a1.JSSJ
      

  4.   

    因为select distinct a1.id from a1,a2 where a1.kssj>=a2.kssj2 and a1.jssj<=a2.jssj2取出来的是在a2里的记录,因为a1没有数据在a2里面,所以没有记录
    select count(*) from (select distinct a1.id from a1,a2 where a1.kssj>=a2.kssj2 and a1.jssj<=a2.jssj2)就是0了
    结果是2>0说明a1中的记录没全在a2中。
      

  5.   

    这样说来,我的也可以用嘛,只是大于小于写反了....SELECT a2.*
      FROM a2, a1
     WHERE a2.kssj2 <= a1.kssj AND a2.jssj2 >= a1.jssj不过重点应该是A1A2的数据应该如何清理,一条SQL能写出来吗
      

  6.   

    贴主:stady(学习),你把汉字打清楚一些,下面的是猜想还是其它
    --------> 就是判断a1中1000到3000中{所以}数据:1000,1001,1002....3000{和}全部在表a2中
      

  7.   

    如果a1,a2表本身的数据就不存在交集,那就好办了
    select (select count(*) from a1)-(select count(*) from (select distinct a1.id from a1,a2 where a1.kssj>=a2.kssj2 and a1.jssj<=a2.jssj2)) from dual
    判断一下,大于零就不满足,等于零就满足
    -----
    我的想法有问题,如果a1,a2表本身的数据就不存在交集,也不能这么做。
    要a1,a2表本身的数据有间隔才行。
      

  8.   

    如果记录是这样的,楼上的方法都不行吧
    SQL> select * from test1;        ID       KSSJ       JSSJ
    ---------- ---------- ----------
             1       1000       2000
             2       2500       3000SQL> select * from test2;        ID       KSSJ       JSSJ
    ---------- ---------- ----------
             1       1000       1500
             2       1501       2510
             3       2511       3000
             4       3111       5000
    也就是说test2.kssj <= test1.kssj AND test2.jssj >= test1.jssj的记录不存在,但test1中所有数据确实包含在test2中的另外一种情况:
    SQL> select * from test1;        ID       KSSJ       JSSJ
    ---------- ---------- ----------
             1       1000       2000
             2       2500       3000
             3       3500       5000SQL> select * from test2;        ID       KSSJ       JSSJ
    ---------- ---------- ----------
             1       1000       1500
             2       1550       2510
             3       2511       3000
             4       3111       5000test2.kssj <= test1.kssj AND test2.jssj >= test1.jssj的记录存在,但是test1中所有数据确不全部包含在test2中的
      

  9.   

    可能上面的没说清楚,举的例子
    a1表中:字段名  : id        kssj(开始数据)        jssj(结束数据)
                        1        1000                     2000
    a2表中:字段名  : id       kssj2(开始数据)        jssj2(结束数据)
                        1        1000                     1500
                        2        1501                     2500
    这种情况按
    select (select count(*) from a1)-(select count(*) from (select distinct a1.id from a1,a2 where a1.kssj>=a2.kssj2 and a1.jssj<=a2.jssj2)) from dual
    是查不出来的
    只有
    a1表中:字段名  : id        kssj(开始数据)        jssj(结束数据)
                        1        1000                     2000
    a2表中:字段名  : id       kssj2(开始数据)        jssj2(结束数据)
                        1        1000                     1500
                        2        1502                     2500
    才行。所以,还是写函数吧。
      

  10.   

    可能我没有说明白我的意思:
    我的意思是判断a1中1000到3000中所有数据:1000,1001,1002....3000每个数都在表a2中
    即:在a1每条记录结束号码和开始号码之间所有的数据都要在a2记录的开始号码和结束号码之间。而且肯定会出现交集。
    能否写一个存储过程:
    先获得a1的记录,再用循环将1000,1001,1002...在a2表中遍寻
      

  11.   

    如果一定会出现交集,就写个function,思路我在上面已经写了。
    你的kssj和jssj有可能相等吗?要是有可能相等就需要改一改
      

  12.   

    PROCEDURE PISA1INTABLEA2(
        pReturnNum                           in out number                            
      )
    is
        vintI                              number:=999999999;                         
        vkssj                                number:=0;                            
        vjssj                                number:=0;                          
        /** 定义例外 **/ 
        exceptionDataNotFind                 EXCEPTION;                                
        /** 定义游标,到A1表取出kssj和jssj **/
        CURSOR C_A1 is                                   
               SELECT kssj,                                                      
                      jssj                                 
               FROM   A1;                   
                
               
    begin
         
        for C_GET_A1 in C_A1 loop
            
            vkssj:=C_GET_A1.kssj;
    vjssj:=C_GET_A1.jssj; 
    begin 
      while vintI >=vjssj loop  
    begin
      select max(jssj2) into vintI from a2 where kssj2<=vkssj;

        exception when no_data_found  then
            raise exceptionDataNotFind;
                end;
        if vintI <vjssj then
        if vintI<= vkssj then
        raise exceptionDataNotFind;
    else
        vkssj:=vintI;
        end if; 
    end if; 
      end loop; 
    end; 
        end loop ;
        pReturnNum:=1;    EXCEPTION
        when exceptionDataNotFind then 
        pReturnNum:=2; 
        
           
    end PIsA1InTableA2;
      

  13.   

    返回1表示a1中的数都在a2里面
    返回2表示a1中的数不都在a2里面
      

  14.   

    是这个,上面的循环判断搞反了
    返回1表示a1中的数都在a2里面
    返回2表示a1中的数不都在a2里面PROCEDURE PISA1INTABLEA2(
        pReturnNum                           in out number                            
      )
    is
        vintI                              number:=0;
        vkssj                                number:=0;                            
        vjssj                                number:=0;                          
        /** 定义例外 **/ 
        exceptionDataNotFind                 EXCEPTION;                                
        /** 定义游标,到A1表取出kssj和jssj **/
        CURSOR C_A1 is                                   
               SELECT kssj,                                                      
                      jssj                                 
               FROM   A1;                   
                
               
    begin
         
        for C_GET_A1 in C_A1 loop
            
            vkssj:=C_GET_A1.kssj;
    vjssj:=C_GET_A1.jssj; 
    begin 
      while vintI <vjssj loop
    begin
      select max(jssj2) into vintI from a2 where kssj2<=vkssj;

        exception when no_data_found  then
            raise exceptionDataNotFind;
                end;
        if vintI <vjssj then
        if vintI<= vkssj then
        raise exceptionDataNotFind;
    else
        vkssj:=vintI;
        end if; 
    end if; 
      end loop; 
    end; 
        end loop ;
        pReturnNum:=1;    EXCEPTION
        when exceptionDataNotFind then 
        pReturnNum:=2; 
        
           
    end PIsA1InTableA2;
    返回1表示a1中的数都在a2里面
    返回2表示a1中的数不都在a2里面
      

  15.   

    pReturnNum                           in out number                            
    这个什么意思,而且我怎么没有看出来那个地方是把数据+1的地方呀
      

  16.   

    pReturnNum是返回值啊,要根据返回值才能知道a1中的数是不是都在a2里面,也是输入的参数,其实把in去了就行了,你也不需要传参。
    我怎么没有看出来那个地方是把数据+1的地方呀
    ------
    好像是少了一个+1
    PROCEDURE PISA1INTABLEA2(
        pReturnNum                           in out number                            
      )
    is
        vintI                              number:=0;
        vkssj                                number:=0;                            
        vjssj                                number:=0;                          
        /** 定义例外 **/ 
        exceptionDataNotFind                 EXCEPTION;                                
        /** 定义游标,到A1表取出kssj和jssj **/
        CURSOR C_A1 is                                   
               SELECT kssj,                                                      
                      jssj                                 
               FROM   A1;                   
                
               
    begin
         
        for C_GET_A1 in C_A1 loop
            
            vkssj:=C_GET_A1.kssj;
    vjssj:=C_GET_A1.jssj; 
    begin 
      while vintI <vjssj loop
    begin
      select max(jssj2) into vintI from a2 where kssj2<=vkssj;

        exception when no_data_found  then
            raise exceptionDataNotFind;
                end;
        if vintI <vjssj then
        if vintI<= vkssj then
        raise exceptionDataNotFind;
    else
        vkssj:=vintI+1;
        end if; 
    end if; 
      end loop; 
    end; 
        end loop ;
        pReturnNum:=1;    EXCEPTION
        when exceptionDataNotFind then 
        pReturnNum:=2; 
        
           
    end PIsA1InTableA2;