选择包含值的范围

问题描述 投票:0回答:2

我有一个包含范围的表:

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

postgresql range
2个回答
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”之类的保留字。逃避这一点非常繁琐。


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

© www.soinside.com 2019 - 2024. All rights reserved.