SQL-范围是否在连续范围内

SQL-范围是否在连续范围内,sql,oracle,range,Sql,Oracle,Range,我真的被难住了 假设我有一个有效数字表,其中的BEGIN_NUM和END_NUM列表示一个有效数字范围。该表的外观如下所示: ID BEGIN_NUM END_NUM -- --------- ------- A 1 10 B 11 20 C 21 30 D 55 70 我们得到了一个范围的开始数和结束数。我需要开发一个SQL查询,看看这个数字范围是否都是有效的数字 简单的例子:给定2和

我真的被难住了

假设我有一个有效数字表,其中的BEGIN_NUM和END_NUM列表示一个有效数字范围。该表的外观如下所示:

ID BEGIN_NUM END_NUM
-- --------- -------
 A       1      10         
 B      11      20
 C      21      30
 D      55      70
我们得到了一个范围的开始数和结束数。我需要开发一个SQL查询,看看这个数字范围是否都是有效的数字

简单的例子:给定2和8作为范围的开始和结束,这将通过,因为它在A行的范围内

困难情况:1给定5和15,这将通过,因为这属于A行和B行,这两行基本上是彼此的延续,形成一个跨越两行的大范围。1-10和11-20=1-20

2给定5和25,这也将通过,原因与1相同,只是它跨越了两行而不是两行。1-10&11-20&21-30=1-30

3给定27和57,这将失败,因为即使开始和结束数字在一个范围内,C行和D行之间也存在间隙,因此这将使给定范围内的数字31-54无效

我真的不必在这个查询中返回任何数据,只需显示该范围包含所有有效数字。如果有必要的话,使用Oracle

以下是我到目前为止的情况:

select count(*) 
from (select start_num, end_num
    from ae_valid_vendor_nums
    where '5' BETWEEN start_num AND end_num) tbl1,
 (select start_num, end_num
    from ae_valid_vendor_nums
    where '25'  BETWEEN start_num AND end_num) tbl2
where (tbl1.end_num - tbl2.start_num = -1) 
OR (tbl1.start_num = tbl2.start_num AND tbl1.end_num = tbl2.end_num)

谢谢你的帮助

有趣的小问题。这样做的目的是计算每个组内的重叠,求和重叠,然后与实际范围进行比较。下面的查询通过一些示例实现了这一点。它的输出比您要求的要多一些,但这应该有助于您了解它是如何工作的:

with ValidNumbers as (
     select 1 as begin_num, 10 as end_num from dual union all
     select 11, 20 from dual union all
     select 21, 30 from dual union all
     select 55, 70 from dual
    )
select v_begin, v_end,
       sum(1 + (case when v_end >= vn.end_num then vn.end_num else v_end end) -
           (case when v_begin >= vn.begin_num then v_begin else vn.begin_num end)
          ) as SumInRecords,
       max(1 + v_end - v_begin) as TheRange,
       (case when sum(1 + (case when v_end >= vn.end_num then vn.end_num else v_end end) -
                      (case when v_begin >= vn.begin_num then v_begin else vn.begin_num end)
                     ) =
                   max(1 + v_end - v_begin)
             then 'All' else 'Missing'
         end)
from ValidNumbers vn cross join
     (select 2 as v_begin, 8 as v_end from dual union all
      select 2, 18 from dual union all
      select 2, 28 from dual union all
      select 2, 38 from dual
     ) const
where v_begin <= vn.end_num and
      v_end >= vn.begin_num
group by v_begin, v_end;

一种方法是使用理货表,然后将理货计数与两个端点加一的差值进行比较,因为这是包容性的

比如这个

WITH validnumbers 
     AS (SELECT 1  AS begin_num, 10 AS end_num FROM   dual 
         UNION ALL SELECT 11, 20          FROM   dual 
         UNION ALL SELECT 21, 30          FROM   dual 
         UNION ALL SELECT 55, 70          FROM   dual), 
     tally 
     AS (SELECT LEVEL num 
         FROM   dual 
         CONNECT BY LEVEL <= 100 
         ORDER  BY LEVEL), 
     test 
     AS (SELECT t.num 
         FROM   validnumbers v 
                inner join tally t 
                        ON v.begin_num <= t.num 
                           AND v.end_num >= t.num 
         WHERE  t.num >= 27 
                AND t.num <= 57) 
SELECT Count(num), 
       (57 - 27) + 1
FROM   test
将57和27替换为25和5,我们将获得正确的通过

COUNT(NUM)   (25-5)+1
---------- ----------
        21         21 

编辑-使用OracleUpdated与我拥有的
COUNT(NUM)   (25-5)+1
---------- ----------
        21         21