如何使用 SQL 找到具有预定义最小间隙大小的所有“间隙”?

How do I find all “gaps” with predefined minimal gap size with SQL?

我阅读了很多关于寻找间隙的好答案 (here, here, ),但我仍然不知道如何找到具有最小预定义尺寸的间隙。

在我的例子中,空白是没有按 HE 排序的条目。

我还需要找到从 table 开头开始的空白,就像示例中那样。

任何人都可以帮助提供一个漂亮干净的 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 |      
+-----------+----+

您可以识别间隙以及起点和终点。要识别差距,请计算非差距的数量并汇总:

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;

编辑二:

在旧版本的 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;