【问题标题】:Finding missing sequence numbers查找丢失的序列号
【发布时间】:2013-10-27 18:03:02
【问题描述】:

我想创建一个表来查找丢失的序列号。 0到70000之间的序列号达到70000后变成0。在特定的时间段内我需要找到那些丢失的记录。

【问题讨论】:

    标签: sql oracle oracle11g sequence


    【解决方案1】:

    此解决方案基于生成从 1 到您设置的某个限制的所有自然数的语句:

    SELECT ROWNUM N FROM dual CONNECT BY LEVEL <= 7000
    

    此解决方案的第二部分是 Oracle MINUS 运算符(通常称为 EXCEPT),旨在减去集合。

    换句话说,最终的查询是:

    SELECT ROWNUM id FROM dual CONNECT BY LEVEL <= 7000
    MINUS
    SELECT id FROM mytable
    

    SQLFiddle demo for 20 numbers.

    【讨论】:

      【解决方案2】:

      您可以使用Lead and lag functions 来检测序列中的空白。
      该解决方案不会限制您使用特定的上限数字,例如 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 demo

      穿越

      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;
      

      【讨论】:

        【解决方案3】:

        我不久前从 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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-11-06
          • 2020-12-07
          • 1970-01-01
          • 2016-03-09
          • 2013-08-31
          • 2020-05-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多