查找值列表的范围 - sql中的“介于”运算符
Posted
技术标签:
【中文标题】查找值列表的范围 - sql中的“介于”运算符【英文标题】:find the range for list of values - 'between' operator in sql 【发布时间】:2016-12-01 16:27:18 【问题描述】:我手头有一系列值。我想找出值所在的表中的范围。
值列表(475747003, 476367781, 454313069, 454545398, etc.,)
— 1000 个值
DB 表中的范围如下所示:
Start_Range End_Range
--------------------------
475747000 475747999
476367781 476367782
454313059 454313069
我的输出应该如下所示,即我想找出所有 1000 个值的 Start_Range
和 End_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 - “此运算符不能与列表一起使用”
所以我想另辟蹊径。
【问题讨论】:
你的值在 x 和 y 之间的带有 MAX() 和 MIN() 或 TOP 1 ORDER BY 和 TOP 1 ORDER BY DESC 的东西会让人想起。 您使用的是哪个 DBMS? 我也看不出这两个例子有什么区别 Oracle 版本 3.2.10.09 数据库表中的 1000 个范围,我想找到值所在的正确范围。但我有一个值列表。不止一个。 【参考方案1】:您将无法使用“正常”查询来做到这一点(最接近的是用于值列表的 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
如果你想使用临时表也是一样。您只需将值放入数据库可以视为 set 的内容中,然后加入您的范围。
【讨论】:
当然这可以通过“正常”查询来完成。IN
不是唯一可用的运算符。 EXISTS
可以与除相等以外的条件一起使用(在这种情况下它可以正常工作)。
只是说您必须将“值列表”转换为基于集合的操作的集合。除此之外,当然,这是正常的。
哦,好吧 - 我以为你的意思是“即使测试值已经在表格中,你也只能使用 IN
并且不能用于范围测试。”如果您的意思是将列表转换为表格,那是另一回事(尽管我使用table(sys.odcinumberlist(..))
说明的方法也很标准)。【参考方案2】:
在下面的查询中,我模仿了 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
)
;
【讨论】:
以上是关于查找值列表的范围 - sql中的“介于”运算符的主要内容,如果未能解决你的问题,请参考以下文章
drupal 8 查看日期范围过滤器-“介于”运算符不包括结束日期