我想创建一个表来查找丢失的序列号。0到70000之间的序列号达到70000后变为0。在特定的时间段内我需要找到那些丢失的记录。
问问题
865 次
3 回答
6
此解决方案基于生成从 1 到您设置的某个限制的所有自然数的语句:
SELECT ROWNUM N FROM dual CONNECT BY LEVEL <= 7000
该解决方案的第二部分是 OracleMINUS
运算符(通常称为EXCEPT
),旨在减去集合。
换句话说,最终查询是:
SELECT ROWNUM id FROM dual CONNECT BY LEVEL <= 7000
MINUS
SELECT id FROM mytable
于 2013-10-26T05:41:37.317 回答
3
您可以使用Lead 和 lag 函数来检测序列中的间隙。
该解决方案不会限制您使用特定的上限数字,例如 70000。
检测:
SELECT *
FROM (SELECT lag(c.id) over(ORDER BY id) last_id,
c.id curr_id,
lead(c.id) over(ORDER BY id) next_id
FROM mytable c
order by id)
WHERE nvl(last_id, curr_id) + 1 <> curr_id
AND last_id IS NOT NULL
Sqlfiddle 演示。
遍历:
begin
FOR x IN (SELECT *
FROM (SELECT lag(c.id) over(ORDER BY id) last_id,
c.id curr_id,
lead(c.id) over(ORDER BY id) next_id
FROM mytable c order by id)
WHERE nvl(last_id, curr_id) + 1 <> curr_id AND
last_id IS NOT NULL
) LOOP
dbms_output.put_line('last_id :' || x.last_id);
dbms_output.put_line('curr_id :' || x.curr_id);
dbms_output.put_line('next_id :' || x.next_id);
dbms_output.put('gaps found: ');
for j in x.last_id + 1 .. nvl(x.next_id,x.curr_id) - 1 loop
if j != x.curr_id then
dbms_output.put(j || ', ');
end if;
end loop;
dbms_output.put_line('');
dbms_output.put_line('*****');
end loop;
end;
于 2013-10-27T05:31:08.250 回答
1
不久前我从 Tom Kyte 那里偷了这个:
select id, one_before, Diff, dense_rank() over (order by Diff desc) rank from (
select id, one_before,
case when (id - one_before) > 1 then (id - one_before)
else 1
end Diff
from (
select id, lag(id) over(order by id) one_before
from table_name order by id) )
原始讨论位于http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:8146178058075。
于 2013-10-26T21:13:36.583 回答