SQL Появление порядкового номера - PullRequest
1 голос
/ 21 февраля 2020

Я хочу выяснить, имеет ли любое Имя прямое 4 или более вхождений SeqNo только в последовательной последовательности. Если в seqNo есть перерыв, но 4 или более строк являются последовательными, тогда мне также нужно это имя.

Пример:

SeqNo    Name
10     | A
15     | A
16     | A
17     | A
18     | A
9      | B
10     | B
13     | B
14     | B
6      | C
7      | C
9      | C
10     | C
OUTPUT:
A

НИЖЕ СЦЕНАРИЙ ДЛЯ ЛЮБОЙ ПОМОЩИ.

create table testseq (Id int, Name char)

INSERT into testseq values
(10, 'A'),
(15, 'A'),
(16, 'A'),
(17, 'A'),
(18, 'A'),
(9, 'B'),
(10, 'B'),
(13, 'B'),
(14, 'B'),
(6, 'C'),
(7, 'C'),
(9, 'C'),
(10, 'C')

SELECT * FROM testseq

Ответы [ 3 ]

0 голосов
/ 21 февраля 2020

Я на самом деле не рассматриваю это как проблему "пробелов и островов". Вы просто ищете минимальное количество соседних строк. Это легко обрабатывается с помощью lag() или lead():

select t.*
from (select t.*,
             lead(seqno, 3) over (partition by name order by seqno) as seqno_name_3
      from t
     ) t
where seqno_name_3 = seqno + 3;

. Проверяется третий порядковый номер с тем же именем. Третий после означает, что четыре имени совпадают в строке.

Если вы просто хотите, чтобы имя и обрабатывали дубликаты:

select distinct name
from (select t.*,
             lead(seqno, 3) over (partition by name order by seqno) as seqno_name_3
      from t
     ) t
where seqno_name_3 = seqno + 3;

Если последовательность числа могут иметь пробелы (но в остальном смежные):

select distinct name
from (select t.*,
             lead(seqno, 3) over (partition by name order by seqno) as seqno_name_3,
             lead(seqno, 3) over (order by seqno) as seqno_3
      from t
     ) t
where seqno_name_3 = seqno_3;
0 голосов
/ 21 февраля 2020

Решение в обычный SQL, нет LAG() или LEAD() или ROW_NUMBER():

SELECT t1.Name
FROM testseq t1
WHERE (
    SELECT count(t2.Id)
    FROM testseq t2
    WHERE t2.Name=t1.Name
          and t2.Id between t1.Id and t1.Id+3
        GROUP BY t2.Name)>=4
GROUP BY t1.Name;
0 голосов
/ 21 февраля 2020

Для этого вы можете использовать некоторые методы пробелов и островков.

Если вы хотите, чтобы name с хотя бы 4 последовательными записями, где seqno увеличивается на 1, тогда вы можете используйте разницу между seqno and row_number () `для определения групп, а затем агрегируйте:

select distinct name
from (
    select t.*, row_number() over(partition by name order by seqno) rn
    from testseq t
) t
group by name, rn - seqno
having count(*) >= 4

Обратите внимание, что для ваших примеров данных это не возвращает строк. A имеет 3 последовательных записи, где seqno увеличивается на 1, B и C имеют две.

...