选择包含值的范围

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了选择包含值的范围相关的知识,希望对你有一定的参考价值。

我有一个包含范围的表:

+----+------+----+
| id | from | to |
+----+------+----+
|  1 |    1 | 10 |
|  2 |   11 | 20 |
|  3 |   21 | 30 |
+----+------+----+

我有一个值列表:(5, 7, 16)

我想选择包含以下值之一的所有范围:

+-------+----------+
| value | range_id |
+-------+----------+
|     5 |        1 |
|     7 |        1 |
|    16 |        2 |
+-------+----------+

或者也许只是包含的范围ID,我也可以使用:(1, 2)

我查看了numrange并使用range operators,但我还没有找到一个运算符来测试多个值。

答案

您将使用<@(元素包含)运算符:

WITH sample (id, "from", "to") AS (
    VALUES 
        (1, 1, 10),
        (2, 11, 20),
        (3, 21, 30)
)
SELECT 
    ranges.val,
    sample.id 
FROM 
    sample
    --You can inject you array of values in a call of unnest function to simplify your query
    JOIN UNNEST(ARRAY[5, 7, 16]) AS ranges(val) ON (ranges.val <@ int4range(sample."from", sample."to"));

还要避免使用“from”和“to”之类的保留字。逃避这一点非常繁琐。

另一答案

范围运算符确实是要走的路:

select t.value, r.id
from ranges r
  join (values (5),(7),(16) ) as t(value)
    on t.value <@ int4range(r."from", r."to");

通过使用values() row constructor创建“虚拟表”,还可以显示匹配值。

如果您希望某些值不匹配,并且您希望该信息使用外部联接:

select t.value, r.id
from ( values (5),(7),(16),(42) ) as t(value) 
  left join ranges r on t.value <@ int4range(r.from, r.to);

在线示例:http://rextester.com/BIKSH85499

以上是关于选择包含值的范围的主要内容,如果未能解决你的问题,请参考以下文章

选择两个不同字段之间的范围包含给定数字的数据

选择两个不同字段之间的范围包含给定数字的数据

使用包含当前值的浮动 DIV 自定义 HTML 范围输入

在包含“无”/“假”值的字典上获取具有最小值的键

Oracle:选择日期范围内缺少值的日期的值

如何从现有排名值创建具有递增排名值的运行范围的表?