Как запросом определить нарушение последовательности?
Есть последовательность записей, у которых в поле А записаны числа. Нормальный вид этой последовательности - непрерывная (1, 2, 3, 4, 5).
Как определить с помощью запроса, нарушена ли последовательность или нет?
Пример нарушения последовательности: (1, 2, 4, 5, 7), либо (1, 2, 2, 3, 4).
Думал как-то через факториал подойти к решению, но не осилил. Может есть у кого-то соображения по поводу решения?
PS Предложеный дубликат не учитывает повторяющиеся значения.
Ответы (2 шт):
последовательность начинается с 0 – Анатолий Эрнст
WITH cte AS ( SELECT number, ROW_NUMBER() OVER (ORDER BY number) - 1 rn
FROM table )
SELECT EXISTS ( SELECT NULL
FROM cte
WHERE number <> rn ) AS not_consecutive
Разница между текушим значением последовательности и порядковым номером записи всегда одно и тоже число, неважно с какого числа начинается отсчёт. Если в результате несколько таких чисел, то где-то есть нарушение последовательности.
Рабочий пример:
with t (seq, num) as (
select 'seq1', column_value from sys.odciNumberList (1, 2, 3, 4, 5) n union all
select 'seq2', column_value from sys.odciNumberList (1, 2, 4, 5, 7) n union all
select 'seq3', column_value from sys.odciNumberList (1, 2, 2, 3, 4) n union all
select 'seq4', column_value from sys.odciNumberList (0, 1, 2, 3, 4) n
)
select seq, case when count (distinct grp)=1 then 'yes' else 'no' end consecutive
from (
select seq, num - row_number() over (partition by seq order by num) grp
from t)
group by seq
order by seq
Результат:
SEQ CONSECUTIVE
---- ------------
seq1 yes
seq2 no
seq3 no
seq4 yes
Если версия 12c и выше, то задачу можно решить с клаузой MATCH_RECOGNIZE:
select seq, case when count (*)=1 then 'yes' else 'no'end consecutive
from t
match_recognize (
partition by seq
order by num
measures null grp
pattern (a b*)
define b as num = prev (num)+1
) group by seq;
SEQ CONSECUTIVE
---- ------------
seq1 yes
seq2 no
seq3 no
seq4 yes