PostgreSQL IP address: Search the right result by inet data?

孤人 提交于 2019-12-20 03:54:21

问题


I have a problem on PostgreSQL when asking if a given IP address (inet type) search the right result in the database. I will provide step by step what I'm doing.

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');

Then I want search ip by '1111:0', which should find the result

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

回答1:


If you want to search for some text representation of inet addresses (with f.ex. LIKE), you'll have a hard time; because inet output is canonized. F.ex.:

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

So, leading zeros are gone & and the largest block of only zeros are replaced with :: (which is completely valid in IPv6).

But, if you want to find inet addresses, which have 20 leading bits like 1111:0, you can use subnets.

For 1111:0, you are really looking for the child (networks / ) hosts of 1111::/20 (with the contains operator: >>):

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)

Will produce:

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




回答2:


select * from test where 
cast((ip)as varchar) like '%a000::%'
or cast((ip)as varchar) like '%a000:_:%'
or cast((ip)as varchar) like '%a000:__:%'
or cast((ip)as varchar) like '%a000:___:%
or cast((ip)as varchar) like '%a000:_____'
or cast((ip)as varchar) like '%a000:______'
or cast((ip)as varchar) like '%a000:_______'


来源:https://stackoverflow.com/questions/42825151/postgresql-ip-address-search-the-right-result-by-inet-data

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!