工作中遇到一个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。
运行环境: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。
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替代你输入的值
不过这个case可以参考下
输入 id = 1为检索条件,这个时候需要返回的结果集是 id = 4;
输入 id = 4为检索条件,这个时候需要返回的结果集是 id = 4;
输入 id = 6为检索条件,这个时候需要返回的结果集是 id = 8;
输入 id = 99为检索条件,这个时候需要返回的结果集是 id = 4(也就是重新从1开始进行检索); 自动检索到表中不存在的id为止
那id=4时,再跳转到id=4,那不是死循环了吗还有,用一段pl/sql代码实现可以吗
楼上的思路正确
稍微需要修改下
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
可以用
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
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;
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
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
mod(min(t.ID)id,99)+1
加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值这样就行了
这样应该可以
我的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的指点