Как найти все «разрывы» с предопределенным минимальным размером разрывов с SQL? - PullRequest
0 голосов
/ 24 марта 2020

Я прочитал много хороших ответов ( здесь , здесь , здесь ) о поиске пробелов, но я все еще не могу понять, как найти пробелы с минимальным предопределенным размером.

В моем случае пробелы - это записи без порядка имен по HE.

Мне также нужно найти пробелы, начиная с начала таблицы, как в примере.

Любой может помочь с красивым и чистым оператором SQL, который можно легко изменить, чтобы получить предопределенные минимальные размеры пропусков?

Пример с ожидаемым результатом:

+-----------+----+      +----------------+      +----------------+      +----------------+
| name      | HE |      |   GAPS >= 1    |      |   GAPS >= 2    |      |   GAPS >= 3    |
+-----------+----+      +-----------+----+      +-----------+----+      +-----------+----+
|           |  1 |      | name      | HE |      | name      | HE |      | name      | HE |
| JohnDoe01 |  2 |      +-----------+----+      +-----------+----+      +-----------+----+
| JohnDoe02 |  3 |      |           |  1 |      |           |  4 |      |           | 12 |
|           |  4 |      |           |  4 |      |           |  5 |      |           | 13 |
|           |  5 |      |           |  5 |      |           |  9 |      |           | 14 |
| JohnDoe03 |  6 |      |           |  9 |      |           | 10 |      +-----------+----+
| JohnDoe04 |  7 |      |           | 10 |      |           | 12 |
| JohnDoe05 |  8 |      |           | 12 |      |           | 13 |
|           |  9 |      |           | 13 |      |           | 14 |
|           | 10 |      |           | 14 |      +-----------+----+
| JohnDoe06 | 11 |      +-----------+----+
|           | 12 |
|           | 13 |      
|           | 14 |      
| JohnDoe07 | 15 |      
+-----------+----+

1 Ответ

1 голос
/ 24 марта 2020

Вы можете определить промежутки и начала и остановки. Чтобы определить пропуски, подсчитайте количество непропусков и агрегируйте:

select min(he), max(he), count(*) as size
from (select t.*, count(name) over (order by he) as grp
      from t
     ) t
where name is null
group by grp;

Затем можно отфильтровать, используя having для пропусков определенного размера, скажем 2:

having count(*) >= 2
Например,

.

Суммирует пропуски, по одному на строку. Это на самом деле кажется мне более полезным, чем отдельная строка для каждой строки.

РЕДАКТИРОВАТЬ:

Если вы действительно хотели исходные строки, вы можете сделать:

select t.*
from (select t.*,
             max(he) filter (where name is not null) over (order by he) as prev_he,
             min(he) filter (where name is not null) over (order by he desc) as next_he,
             max(he) over () as max_he
      from t
     ) t
where name is null and
      (max(next_he, max_he + 1) - coalesce(prev_he, 0) - 1) >= 2;

РЕДАКТИРОВАТЬ II:

В более старых версиях MySQL / MariaDB вы можете использовать переменные:

select min(he), max(he), count(*) as size
from (select t.*,
             (@grp := @grp + (name is not null)) as grp
      from (select t.* from t order by he) t cross join
           (select @grp := 0) params
     ) t
where name is null
group by grp;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...