如何根据范围值进行查找

时间:2018-03-08 22:04:47

标签: sql postgresql range

我有一张表:

id          name
001to005    ABC
006to210    PQR
211to300    XYZ

这不是最终表格,我可以按照我想要的方式进行...所以我想在id和提取名称上查找这些数据,如果id在001-005范围内,然后是ABC,如果id是在范围006-010 ....然后命名XYZ。

我的方法是,将id作为正则表达式存储在表中,如下所示:

id                 name
[0][0][1-5]        ABC
[0-2][0-9][0-9]    PQR
[2-3][0-9][0-9]    XYZ

然后查询:

select * from table where '004' ~ id

此查询将返回ABC,这是正确的但是当范围变大时,我的输入值可以位于第2行和第3行。 对于Eg:

select * from table where '299' ~ id

这个查询将导致2行,所以我的问题是使用reg exp来使其更具限制性,或者是否有其他方法可以解决这个问题:

1 个答案:

答案 0 :(得分:1)

存储简单范围的正则表达式,这将非常昂贵并且不能使用索引:必须为每个查询计算表中的每个表达式以满足条件。

您可以range types使用@a_horse already hinted。但是,虽然您不需要添加functionality for range types,但这种简单的布局更小更快:

CREATE TABLE tbl (
   id_lo int NOT NULL
 , id_hi int NOT NULL
 , name text NOT NULL
);

INSERT INTO t VALUES
  (  1,   5, 'ABC')
, (  6, 210, 'PQR')
, (211, 300, 'XYZ');

CREATE UNIQUE INDEX foo ON t (id_lo, id_hi DESC);

两个integer占用8个字节,int4range值占用17个字节。大小在表和索引中很重要。

查询:

SELECT * FROM tbl
WHERE  4 BETWEEN id_lo AND id_hi;

下方(id_lo)和上方(id_hi)边界包含在范围内,就像您的示例数据似乎建议的那样。
请注意,范围类型默认排除上限。

同时假设前导零是无关紧要的,因此我们可以使用普通integer进行操作。

相关:

在表格中强制执行不同的范围:

您仍然不需要表中的范围类型: