检查范围是否重叠

问题描述 投票:0回答:2

我有一张这样的桌子:

Id  min_val  max_val
1   5        7
2   8        12
3   4        6

如果min_val和max_val与任何其他ID重叠,我想得到True / False。因此,结果如下:

Id result
1  True  
2  False 
3  True

谢谢。

mysql sql sqlite gaps-and-islands
2个回答
1
投票

一种方法使用exists

select t.*,
       (exists (select 1
                from t t2
                where t2.id <> t.id and
                      t2.max_val > t.min_val and
                      t2.min_val < t.max_val
               )
       ) as result;
from t;

另一种方法使用窗口函数。如果周期可以同时开始,则有点棘手,但想法是:

select t.*,
       (max(max_val) over (order by min_val range between unbounded preceding and 1 preceding) > min_val) or
        min(min_val) over (order by max_val desc range between unbounded preceding and current row)
       ) as result
from t;

0
投票

这可能是矫kill过正,但您可以使用JOIN,如下所示,不仅可以知道是否存在重叠,而且可以知道重叠的是什么:

SELECT t.id, tOther.id As overlappingId
FROM t
LEFT JOIN t AS tOther 
   ON t.id <> tOther.id            -- Not the same record
   AND t.min_val < tOther.max_val  -- Starts before "other" ends
   AND t.max_val > tOther.min_val  -- Ends after "other" starts
;

如果只希望每t个结果行,则可以通过聚合调整查询。

SELECT t.id
    , COUNT(tOther.id) AS overlappingCount
    , GROUP_CONCAT(tOther.id) AS overlappingIDs
FROM t
LEFT JOIN t AS tOther 
   ON t.id <> tOther.id            -- Not the same record
   AND t.min_val < tOther.max_val  -- Starts before "other" ends
   AND t.max_val > tOther.min_val  -- Ends after "other" starts
GROUP BY t.id
;

如果将共享边界视为重叠,只需将><分别更改为>=<=

© www.soinside.com 2019 - 2024. All rights reserved.