选择包含值的范围

时间:2018-08-30 15:32:35

标签: postgresql range

我有一个包含范围的表:

+----+------+----+
| 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,但我没有找到  用于测试多个值的运算符。

2 个答案:

答案 0 :(得分:0)

范围运算符确实是可行的方法:

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

答案 1 :(得分:0)

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

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”。避免这种情况非常繁琐。