几天前,我看到一个问题,除其他外,暗示了一个与我将要提出的问题相似的问题,我想以更一般的方式来做,因为我知道适当的解决方案可以作为类似问题的参考。也许对于你们中的一些人来说,答案是微不足道的或显而易见的,但就我而言,只有当我咀嚼足够多时,我才发现(至少我是这么认为的)它比我想象的要简单。我在 Sql 中提出它,但它可能更多关于算法,问题是能够测试解决方案似乎更实用。
假设以下示例:
CREATE TABLE A (
NRO_DESDE INT,
NRO_HASTA INT
)
CREATE TABLE B (
NRO_DESDE INT,
NRO_HASTA INT
)
INSERT INTO A (NRO_DESDE, NRO_HASTA)
VALUES (5, 8)
INSERT INTO B (NRO_DESDE, NRO_HASTA)
VALUES (1, 2), (4, 5), (5, 8), (6, 7), (7, 9), (4, 10), (9, 11)
SELECT NRO_DESDE, NRO_HASTA FROM A;
SELECT NRO_DESDE, NRO_HASTA FROM B;
该表A
有一个值:
NRO_DESDE NRO_HASTA
========= =========
5 8
董事会B
NRO_DESDE NRO_HASTA
========= =========
1 2
4 5
5 8
6 7
7 9
4 10
9 11
表格A
和B
代表区间的集合,但我们没有所有的值,而是我们知道每个集合的第一个和最后一个元素,想法是将唯一的集合A
与所有的进行比较B
并确定它们是否共享任何元素。例如,记录与B
(4, 5)
共享,不共享任何元素,共享。结果将是那些与那些共享元素 的记录5
A
(1, 2)
(7, 9)
7, 8
B
A
,知道它们是什么并不重要,只知道有,我们也可以假设每个集合中的元素数量是相对可控的。不要担心缺少主键,这只是一个概念示例。
注意:代码是在SQL Server中构建的,但可以在任何“风格”的 SQL 中解析。
gbianchi 的回答有效地回答了我的问题,查看了可以连接间隔的 4 种不同情况。让我们来看看:
案例 1 和 2 是集合的经典交集,是区间,一个可以位于另一个之前,并且在它们的末端有接触。例如,在该示例中,它是区间
4-5
或通过其一端7-9
连接到区间的区间。A
5-8
另外两种可能的情况是包含情况,其中一组包含在另一组中。例如区间
B (6-7)
包含在 中A (5-8)
,反之亦然,A
包含在 中B (4-10)
。要考虑这 4 种情况,并且由于我们拥有的关于集合的唯一数据是它们的限制,因此必须按照 gbianchi 的说明解决查询。看待这个问题的另一种方法是认为案例不满足这些条件。如果我们去理论,唯一的情况是不相交集,即:
未连接的集合,即间隔,情况为两个,当
B
它小于A
或反之亦然。如果我们现在研究如何比较限制,我们会发现它要简单得多,它将是:有趣的是,这些情况的否定是以前的情况之一,因此我们可以将原始查询简化为以下内容:
或者更好的是,使用显式连接:
或者正如 Fede H 所说,应用一些代数来删除
NOT
:虽然这是一个概念性的例子,但实际上我们可以找到许多类似的情况,例如,在某些问题中通常以这种方式处理日期:
我不知道这是否是地球上性能最高的查询......但你有一个固定的问题。
通过这样的查询,您正在寻找相交的两组的所有变体。
请注意,我们首先针对 B 的区间测试 A。然后我们对 B 做同样的事情。后者,因为如果 A 的区间完全包含 B 的区间,那么它不会在第一个查询中出现。
对我来说,最清晰的解决方案类似于 Patricio 的解决方案,但条件相反。就在最近,我不得不将它与日期一起使用,也许在这种情况下它会被更好地理解。我将尝试对其进行解释,看看是否被理解。
我正在寻找的范围是那些在目标范围开始之后结束并在目标范围结束之前开始的范围。