如何使用 SQL 找到具有预定义最小间隙大小的所有“间隙”?
Posted
技术标签:
【中文标题】如何使用 SQL 找到具有预定义最小间隙大小的所有“间隙”?【英文标题】:How do I find all “gaps” with predefined minimal gap size with SQL? 【发布时间】:2020-03-24 18:48:42 【问题描述】:我阅读了很多关于寻找差距的好答案(here、here、here),但我仍然不知道如何找到具有最小预定义大小的差距。
在我的情况下,空白是 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 |
+-----------+----+
【问题讨论】:
。 .如果HE
有差距怎么办?
这是一种没有间隙的约束。表格代表一个柜子,HE(HeightUnit)是它的每个隔间。
【参考方案1】:
您可以识别间隙以及起点和终点。要识别差距,请计算非差距的数量并汇总:
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;
【讨论】:
谢谢,您的解释帮助很大,我非常喜欢这个解决方案,但我混淆了我们的数据库设置。我们正在使用 mariadb-5.5(它基于 MySQL 5.5),看起来它不支持窗口功能。 """SELECT t.*, COUNT(name) OVER (ORDER BY HE) as grp FROM Table t""" 表示 SQL 语法错误。你能想到任何不使用窗口函数的解决方案吗?以上是关于如何使用 SQL 找到具有预定义最小间隙大小的所有“间隙”?的主要内容,如果未能解决你的问题,请参考以下文章