我有一张表:
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来使其更具限制性,或者是否有其他方法可以解决这个问题:
答案 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
进行操作。
相关:
在表格中强制执行不同的范围:
您仍然不需要表中的范围类型: