工作中遇到一个sql,请教各位以下问题,点拨一下思路和解决办法,谢谢!! 
运行环境:oracle 10g ~ 11g
主要是个user master表,id为主键,如下例 
T_USER ID(number(2))  NAME(nvarchar2(2)) 
1                张三 
2                .. 
3                .. 
6                .. 
7                .. 
10              .. 
.. 
99 现在的目的是需要进行这样的查询: 输入 id = 1为检索条件,这个时候需要返回的结果集是 id = 4; 
输入 id = 4为检索条件,这个时候需要返回的结果集是 id = 4; 
输入 id = 6为检索条件,这个时候需要返回的结果集是 id = 8; 
输入 id = 99为检索条件,这个时候需要返回的结果集是 id = 4(也就是重新从1开始进行检索); 这个sql想达到的目的是输入一个值,sql就可以在数据库中找到这个大于等于这个值且在数据库中不存在的id,如果该值存在就依次+1去重新进行检索直至找到不存在的ID。

解决方案 »

  1.   

    select ...
    from ...
    where id=case your_value 
                 when 1 then 4
                 when 4 then 4
                 when 6 then 8
                 when 99 then 4
                 else your_value endyour_value替代你输入的值
                           
      

  2.   

    看错了
    不过这个case可以参考下
      

  3.   

    非常感谢你提供的思路 可能case或decode之类的话没办法解决,因为输入值和结果值都是未知的
      

  4.   

    我没看懂你的问题
    输入 id = 1为检索条件,这个时候需要返回的结果集是 id = 4; 
    输入 id = 4为检索条件,这个时候需要返回的结果集是 id = 4; 
    输入 id = 6为检索条件,这个时候需要返回的结果集是 id = 8; 
    输入 id = 99为检索条件,这个时候需要返回的结果集是 id = 4(也就是重新从1开始进行检索); 自动检索到表中不存在的id为止
    那id=4时,再跳转到id=4,那不是死循环了吗还有,用一段pl/sql代码实现可以吗
      

  5.   

    select min(t.ID) from T_user t where not exists ( select 1 from T_user t2 where t2.ID=t.ID+1) and t.ID>给定的ID
      

  6.   

    终于理解了...
    楼上的思路正确
    稍微需要修改下
    select min(t.ID) from T_user t where not exists ( select 1 from T_user t2 where t2.ID=t.ID+1) and t.ID>=case 给定的ID when 99 then 1 else 给定ID end
      

  7.   

    或者那个表不大的话
    可以用
    select mod(min(t.ID)id,99) from( 
    select * from T_user
    union all
    select id+99,name from t_user) t 
    where not exists ( select 1 from T_user t2 where t2.ID=t.ID+1) 
    and t.ID>=case 给定的ID 
      

  8.   


    drop table t_user;
    create table t_user (id  number, name  varchar2(20));insert into t_user values(1, '张三');
    insert into t_user values(2, '李四');
    insert into t_user values(6, '王五');
    insert into t_user values(7, '马六');
    insert into t_user values(9, '麻七');
    commit;drop table tmp_user;
    create global temporary table tmp_user(id number) on commit preserve rows;create or replace function f_findid
    (
        i_id                    number
    )return number
    as
        v_maxid                 number;
        v_id                    number;
        v_return                number;
    begin
        v_id := i_id;
        select nvl(max(id), 1) into v_maxid from t_user;    delete from tmp_user;
        for i in 1..v_maxid
        loop
            insert into tmp_user(id) values(i);
        end loop;    if v_id >= v_maxid then
            v_id := 1;
        end if;    delete from tmp_user
         where id in(select id from t_user);
        commit;    select min(id) into v_return from tmp_user where id >= v_id;    return v_return;
    exception
        when others then
            dbms_output.put_line(substr(sqlerrm, 1, 200));
            v_return := -1;
            return v_return;
    end f_findid;
      

  9.   

    还应该加1才对
    select mod(min(t.ID)id,99)+1 from( 
    select * from T_user 
    union all 
    select id+99,name from t_user) t 
    where not exists ( select 1 from T_user t2 where t2.ID=t.ID+1) 
    and t.ID+1>=case 给定的ID 
      

  10.   

    select mod(min(t.ID)id,99)+1 from( 
    select * from T_user 
    union all 
    select id+99,name from t_user) t 
    where not exists ( select 1 from T_user t2 where t2.ID=t.ID+1) 
    and t.ID+1>= 给定的ID 
      

  11.   

    select min(t.ID) from T_user t where not exists ( select 1 from T_user t2 where t2.ID=t.ID+1) and t.ID>= 给定的ID这段sql思路可能有些问题,因为传进来的id值在数据库中不存在的时候,无法检索出自己,min(t.id)检索的是数据库中的值,再次谢谢大家的帮助
      

  12.   

    你一定要用一条 sql 语句写出来吗?
      

  13.   

    10 楼的语句明显有语法问题的,
    mod(min(t.ID)id,99)+1
      

  14.   


    加mod的时候忘了把列别名id移出来
    mod(min(t.id),99)+1 id
    后面也忘了加个mod
    select mod(min(t.ID),99)+1 id from( 
    select * from T_user 
    union all 
    select id+99 from t_user) t 
    where not exists ( select 1 from T_user t2 where t2.ID=mod(t.ID,99)+1) 
    and t.ID+1>= 输入的id值这样就行了
      

  15.   

    select decode(sign(mid,给定ID),1,给定ID,mid) from (select min(t.ID) mid from T_user t where not exists ( select 1 from T_user t2 where t2.ID=t.ID+1) and t.ID>= 给定ID ) tr
    这样应该可以
      

  16.   

    谢谢各位的提示,问题已经解决
    我的sql修改成这样,LPAD主要是补0
    SELECT DECODE(ID_CNT,
                  0,
                  给定的ID,
                  (SELECT LPAD(MIN(T.ID) + 1, 7, '0')
                     FROM T_user T
                    WHERE NOT EXISTS (SELECT 1
                             FROM T_user T2
                            WHERE T2.ID = T.ID + 1)
                      AND T.ADER_CD >= 给定的ID)) AS ID
      FROM (SELECT COUNT(T1.ID) AS ID_CNT
              FROM T_user T1
             WHERE T1.ID = 给定的ID)感谢 wildwave,opps_zhou,youthon的指点