Как использовать «группировать по» для группировки данных по IP - PullRequest
1 голос
/ 04 мая 2020

Как использовать group by для группировки данных по диапазону IP в postgres?

Моя таблица:

   "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

Ответы [ 2 ]

1 голос
/ 04 мая 2020

Гордон накрыл это как строки . Хранение и обработка IP-адресов в виде строк делает этот и другие процессы медленными, сложными и тупыми.

Вместо этого сохраняйте их как cidr и используйте set_masklen для группируйте адреса по их /24.

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

Хотя этот конкретный запрос может не принести пользы, cidr может быть проиндексирован с использованием gist с inet_ops для пользы других запросы.

create index on mytable using gist(netaddr inet_ops);

Если вы не можете изменить тип столбца, вы все равно можете использовать функции cidr для приведения типов. set_masklen(netaddr::cidr, 24)

1 голос
/ 04 мая 2020

Я не уверен, что 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]).*$', '\1') as typec,
       count(*)
from t
group by typec
...