当我询问给定的IP地址(inet
类型)是否在数据库中搜索到正确的结果时,我在PostgreSQL上遇到了一个问题。我会一步一步地提供我正在做的事情。
CREATE TABLE public.test (
ip inet,
a character varying
);
INSERT INTO public.test (ip, a) VALUES
('1111:0000:0101:000A:0002:0003:0004:0005', 'admin1'),
('1111:0001:0101:000A:0002:0003:0004:0005', 'admin2'),
('1111:0011:0101:000A:0002:0003:0004:0005', 'admin3'),
('1111:0111:0101:000A:0002:0003:0004:0005', 'admin4'),
('1111:1111:0101:000A:0002:0003:0004:0005', 'admin5');
然后我想通过搜索找到结果
1111:0000:0101:000A:0002:0003:0004:0005
1111:0001:0101:000A:0002:0003:0004:0005
1111:0011:0101:000A:0002:0003:0004:0005
1111:0111:0101:000A:0002:0003:0004:0005
最佳答案
如果您想搜索inet
地址的文本表示形式(使用f.ex.LIKE
),您将很难找到,因为inet
输出是规范化的。传真:
input | output
1111:0000:0000:0000:0000:0000:0000:0005 | 1111::5/128
1111:0001:0101:000A:0002:0003:0004:0005 | 1111:1:101:a:2:3:4:5/128
因此,前导零消失了,只有零的最大块被替换为
::
(这在IPv6中是完全有效的)。但是,如果你想找到
inet
addresses,它有20个前导位,比如1111:0
,你可以使用subnets。对于
1111:0
,您实际上是在寻找1111::/20
(带有contains operator: >>
)的子(networks/)主机:select addr,
inet '1111::/20' >> addr "is within '1111::/20'"
from (values (inet '1111:0000:0000:0000:0000:0000:0000:0005'),
(inet '1111:0001:0101:000A:0002:0003:0004:0005'),
(inet '1111:0011:0101:000A:0002:0003:0004:0005'),
(inet '1111:0111:0101:000A:0002:0003:0004:0005'),
(inet '1111:1111:0101:000A:0002:0003:0004:0005'),
(inet '1111:F111:0101:0000:0000:0000:0000:0005')) v(addr)
将产生:
addr | is within '1111::/20'
1111::5/128 | t
1111:1:101:a:2:3:4:5/128 | t
1111:11:101:a:2:3:4:5/128 | t
1111:111:101:a:2:3:4:5/128 | t
1111:1111:101:a:2:3:4:5/128 | f
1111:f111:101::5/128 | f
http://rextester.com/ZFFFK28291
关于postgresql - PostgreSQL IP地址:通过inet数据搜索正确的结果?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42825151/