找到值列表的范围 - 在sql中的'between'运算符

时间:2016-12-01 16:27:18

标签: sql oracle range between

我手头有值列表。我想在表格中找出值落在的范围。

值列表(475747003, 476367781, 454313069, 454545398, etc.,) - 1000的值

DB表中的范围如下所示:

Start_Range      End_Range
--------------------------
475747000        475747999
476367781        476367782
454313059        454313069

我的输出应如下所示,即我想找出所有1000个值的Start_RangeEnd_Range。我尝试使用'Between'运算符,但是我不确定如何将它用于'值列表'?

Start_Range      End_Range
--------------------------
475747000        475747999
476367781        476367782
454313059        454313069

基本上,下面的sql脚本会抛出错误,

select * from TABLE 
where (475747003, 476367781, 454313069, 454545398) between start_range and end_range;
  

ORA-01796:此运算符不能与列表一起使用   01796. 00000 - “此运算符不能与列表一起使用”

所以我想找到另一种方式。

2 个答案:

答案 0 :(得分:0)

您将无法使用“普通”查询执行此操作(对于值列表,最接近的是IN运算符,但您无法测试除了相等之外的任何内容)。

如何使用临时表,甚至是“虚拟”表,如下所示:

select myValues.myValue, r.Start_Range, r.End_Range
from (
    select 11111 as MyValue from dual union all
    select 22222 as MyValue from dual union all
    select 33333 as MyValue from dual union all
    ... // all of the values you want to search for
    select 99999 as MyValue from dual
) as myValues
inner join RangesTable r on myValues.myValue between r.Start_Range and r.End_Range

如果你想使用临时表,也一样。您只需将值放入数据库可以视为的值,然后连接到您的范围。

答案 1 :(得分:0)

在下面的查询中,我模仿了CTE中的范围表(不是解决方案的一部分;在你的现实问题中,你只需要在主查询中引用你的表),我输入数字“是检查范围“作为动态构建的数字表。你说你只需要在下面的查询中显示匹配的范围我显示每个单独的值和它匹配的范围(如果值不在任何范围内,则显示NULL)。如果您只需要实际匹配,请将left outer join更改为inner join。如果只需要范围,则不要在输出中包含val(在SELECT子句中)。

with
     ranges_table ( start_range, end_range ) as (
       select 475747000, 475747999 from dual union all
       select 476367781, 476367782 from dual union all 
       select 454313059, 454313069 from dual
     ),
     list_of_values ( val ) as (
       select column_value from table(sys.odcinumberlist
                 (475747003, 476367781, 454313069, 454545398))
     )
select l.val, r.start_range, r.end_range
from   list_of_values l left outer join ranges_table r
                          on l.val between r.start_range and r.end_range
;

VAL        START_RANGE  END_RANGE
---------  -----------  ---------
454313069  454313059    454313069
454545398
475747003  475747000    475747999
476367781  476367781    476367782

如果您只需要DISTINCT匹配范围(这比仅从上表中删除VAL列更有意义),您可以改为执行以下操作:

select start_range, end_range
from   ranges_table
where  exists ( select val 
                from   list_of_values 
                where  val between start_range and end_range
              )
;