如何使用"group by"按IP分组数据

How to use "group by" to group data by the IP

如何在postgres中使用group by按IP范围对数据进行分组?

我的table:

   "NETADDR"    |
----------------|
 192.168.13.6   |   
 192.168.13.6   |
 192.168.14.5   |
 192.168.14.6   |

期望输出:

   "NETADDR"    |    "COUNT"
----------------|----------------|
 192.168.13     |      2
 192.168.14     |      2

我不确定 cidr 是否会提高效率,因为您仍然需要聚合。您可以使用数组函数构造 C 类地址:

select array_to_string((regexp_split_to_array(netaddr, '\.'))[1:3], '.') as typec,
       count(*)
from t
group by typec;

或使用正则表达式:

select regexp_replace(netaddr, '(^[0-9]+[.][0-9]+[.]+[0-9]).*$', '') as typec,
       count(*)
from t
group by typec

。将 IP 地址存储和处理为字符串会使这个过程和其他过程变得缓慢、困难和迟钝。

相反,将它们存储为 cidr and use set_masklen 以按 /24 对地址进行分组。

select
  set_masklen(netaddr, 24) as subnet,
  count(*)
from mytable
group by subnet

虽然它可能对这个特定的查询没有好处,但可以使用 gist with inet_opscidr 进行索引以使其他查询受益。

create index on mytable using gist(netaddr inet_ops);

如果您不能更改列类型,您仍然可以使用带转换的 cidr 函数。 set_masklen(netaddr::cidr, 24)