views:

83

answers:

3

Given a table containing dotted quad IPv4 addresses stored as a VARCHAR(15), for example:

     ipv4
--------------
 172.16.1.100
 172.16.50.5
 172.30.29.28

what's a convenient way to SELECT all "ipv4" fields with the final two octets scrubbed, so that the above would become:

    ipv4
------------
 172.16.x.y
 172.16.x.y
 172.30.x.y

Target RDBMS is postgresql 8.4, but the more portable the better!

Thanks.

UPDATE: while I do appreciate (and do upvote) slick INET/CIDR answers, I am looking to produce a string output with non-numeric characters substituted for the final two octets. (And, again, the more portable the better!)

+3  A: 

For postgres:

select regexp_replace('172.16.1.100', E'(.\\d+){2}$', '.x.y');
Konrad Garus
my postgres told me to write it as select regexp_replace('172.16.1.100', E'(.\\d+){2}$', '.x.y');
Unreason
+1. This is kindred to, but a clear improvement on, my original approach, which was: `SUBSTRING("ipv4" FROM E'^(([1-9][0-9]{0,2}\.){2})') || 'x.y'` Thanks!
pilcrow
Don't use a regex when you don't need one. Just use the propper network functions and operators.
Frank Heikens
+1  A: 

Conventional is to convert column type to inet/cidr

EDIT: With this native data type there's quite a few specific functions that perform much better than any string manipulation.

Unreason
Thanks, goran. In fact the source records are INET type. But how would this help me to conceal the last two octets? (Seems to me I need to convert to a string-type and munge from there.)
pilcrow
+3  A: 

If you use the Postgres inet type, then you can do this with the inet operators, eg. <<= means 'is contained within'. I suspect that something lik the following will do what you need:

select my_ipaddress & inet '255.255.0.0' from my_ip_table;

Manual reference: http://www.postgresql.org/docs/8.4/static/functions-net.html

ar
+1 That's not bad, smashing the final two octets to zero...
pilcrow
This is how you do it!
Frank Heikens