Sql 查找表记录中缺少的间隙

Sql 查找表记录中缺少的间隙,sql,oracle,oracle-sqldeveloper,Sql,Oracle,Oracle Sqldeveloper,我有一份此类表格记录列表: 20180108001 20180108002 20180108003 20180108004 等等 在某一点上,这个序列像这样破裂了 20180108099 20180108102 丢失100和101记录 是否有select命令提取第一条非顺序记录 要返回20180108100,请选择上一行并添加1 select min(col + 1) from tablename where col + 1 not in (select col from tablenam

我有一份此类表格记录列表:

20180108001
20180108002
20180108003
20180108004 
等等

在某一点上,这个序列像这样破裂了

20180108099
20180108102
丢失100和101记录


是否有select命令提取第一条非顺序记录

要返回20180108100,请选择上一行并添加1

select min(col + 1)
from tablename
where col + 1 not in (select col from tablename)
使用滞后函数,如下所示:

with t (a) as (
  select 20180107099 from dual union all
  select 20180108002 from dual union all
  select 20180108003 from dual union all
  select 20180108004 from dual )
select a from (select a, lag(a) over(order by a) + 1 as lg from t)
  where lg <> a

您可以使用子查询和自联接

select min(t.id) from t
where t.id  in (

   select t1.id from t t1
          left  join t t2 on t1.id=t2.id+1
          where t2.id is null
               )
您可以使用行号:


以下是列出某个日期的所有孔的另一种方法:

SELECT x AS gap_from, next_x AS gap_to
  FROM ( SELECT x, LEAD(x) OVER (ORDER BY x) next_x
            FROM ( SELECT SUBSTR(the_column,-4,3) AS x 
                         FROM the_table 
                         WHERE the_column LIKE '201808%'
                        )
  )
  WHERE x <> next_x-1

这是一个缺口和孤岛问题。按id生成行号,然后获取顺序记录组

然后使用聚合函数从这些组中获取最小和最大id

MINID-1非顺序记录结束 MAXID+1非顺序记录开始。 最终使用LEAD获取下一个非顺序记录开始值

你可以试试这个

with cte as (
    SELECT MIN(ID) -1  startnum,MAX(ID) +1 endnum
    FROM (
       SELECT  id,id - ROW_NUMBER() OVER(ORDER BY id) grp
       FROM T
    ) t1
    group by grp
)

SELECT endnum from_gap,to_gap 
FROM (
    select *,lead(startnum) over(order by startnum) to_gap
    from cte
) t1
where t1.to_gap is not null

到目前为止你试过什么-编写查询从一个算法开始。那么:是什么使20180108102记录与之前的记录不同?您希望结果是100、101还是102?这太复杂了。同一表的in子句中的自反联接?我敢说,你几乎看不出这本书有什么可读性。看看jarlh的答案,这实际上是多么简单。jarlh在寻找差距;如果您查找创建间隙的现有记录,则必须是mincol,而col-1不在其中。
gap_from | gap_to
-----------------
099      | 102
etc...
with cte as (
    SELECT MIN(ID) -1  startnum,MAX(ID) +1 endnum
    FROM (
       SELECT  id,id - ROW_NUMBER() OVER(ORDER BY id) grp
       FROM T
    ) t1
    group by grp
)

SELECT endnum from_gap,to_gap 
FROM (
    select *,lead(startnum) over(order by startnum) to_gap
    from cte
) t1
where t1.to_gap is not null