Reputation: 19
I want to create a table to find missing sequence numbers. Sequence number between 0 to 70000 after reaching 70000 it becomes 0. In a particular period of time I need to find those missing records.
Upvotes: 2
Views: 978
Reputation: 7284
You may use Lead and lag functions to detect the gaps in the sequence.
The solution will not limit you for a specific upper bound number like 70000.
Detecting:
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 demo.
Traversing:
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;
Upvotes: 3
Reputation: 21
I stole this from Tom Kyte a while ago:
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) )
The original discussion is located at http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:8146178058075.
Upvotes: 1
Reputation: 116197
This solution is based on statement which generates all natural numbers from 1 to some limit you set:
SELECT ROWNUM N FROM dual CONNECT BY LEVEL <= 7000
Second part of this solution is Oracle MINUS
operator (more commonly known as EXCEPT
), which is designed to subtract sets.
In other words, final query is:
SELECT ROWNUM id FROM dual CONNECT BY LEVEL <= 7000
MINUS
SELECT id FROM mytable
SQLFiddle demo for 20 numbers.
Upvotes: 6