Найти пропущенные пробелы в табличных записях - PullRequest
0 голосов
/ 10 сентября 2018

У меня есть список записей таблицы такого типа:

20180108001
20180108002
20180108003
20180108004 

и т. Д.

В какой-то момент эта последовательность распалась вот так

20180108099
20180108102

отсутствует 100 и 101 запись

Есть ли команда "select" для извлечения первой не последовательной записи?

Ответы [ 6 ]

0 голосов
/ 10 сентября 2018

Это проблема пробелов и островов. сделать номер строки по идентификатору, затем получить последовательную группу записей.

, затем используйте агрегатную функцию для получения MIN и MAX id из этой группы.

  • MIN(ID) -1 НЕ конец последовательной записи
  • MAX(ID) + 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
0 голосов
/ 10 сентября 2018

Вот альтернативный способ перечислить все «дыры» на определенную дату:

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

Будет возвращено:

gap_from | gap_to
-----------------
099      | 102
etc...
0 голосов
/ 10 сентября 2018

Вы можете использовать row_number():

select t.* 
from (select t.*, id - (row_number() over (order by id)) as seq
      from table t
     ) t
where seq > 0;
0 голосов
/ 10 сентября 2018

вы можете использовать подзапрос и самостоятельное соединение

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
               )
0 голосов
/ 10 сентября 2018

Используйте функцию lag(), как здесь:

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
0 голосов
/ 10 сентября 2018

Чтобы вернуть 20180108100, выберите предыдущую строку и добавьте 1.

select min(col + 1)
from tablename
where col + 1 not in (select col from tablename)
...