gpt4 book ai didi

sql - 计算每个最小网络 block 的记录(间隔)

转载 作者:行者123 更新时间:2023-11-29 12:39:10 25 4
gpt4 key购买 nike

在 SQL (postgresql 8.4.x) 中,我如何有效地COUNT IP 记录的数量落入可能的最小 netblock包括网 block ?例如,我不想在 10/80/0 下计算 10.0.0.1

更具体地说,给定:

-- CREATE TABLE iplog (ip INET NOT NULL, ...)
--
ip | ...
==============+=====
192.168.1.100 | ...
192.168.1.101 | ...
192.168.55.5 | ...
10.1.2.3 | ...

-- CREATE TABLE netblocks (nb CIDR UNIQUE NOT NULL, ...)
--
nb | ...
===============+======
192.168.1.0/24 | ...
192.168.0.0/16 | ...
10.0.0.0/8 | ...
0.0.0.0/0 | ...

如何高效地生成结果集:

       nb      | ips_logged
===============+============
192.168.1.0/24 | 2
192.168.0.0/16 | 1
10.0.0.0/8 | 1

最佳答案

这对我适用于 8.3 - 在 8.4 上也应该没问题。我们需要自定义聚合,因为 max(cidr) 不是内置的(尽管 > 是内置的)

create or replace function greatest_pair(cidr, cidr) 
returns cidr
language 'sql' immutable as
$$select greatest($1, $2);$$;

create aggregate max( basetype = cidr,
sfunc = greatest_pair,
stype = cidr );

select max_nb, count(*)
from ( select ip, max(nb) as max_nb
from netblocks n join iplog i on(i.ip << n.nb)
group by ip ) z
group by max_nb;

max_nb | count
----------------+-------
192.168.1.0/24 | 2
10.0.0.0/8 | 1
192.168.0.0/16 | 1

如果你不想要自定义聚合,你可以这样做:

create or replace view v as
select ip, nb from netblocks n join iplog i on(i.ip << n.nb);

select nb, count(*)
from ( select *
from v o
where not exists ( select *
from v i
where i.ip=o.ip and i.nb>o.nb ) ) z
group by nb;

或类似使用 with 子句并且在 8.4 上没有 View ,但问题是有效地 :-)

使用这些 View 进行测试:

create or replace view iplog as
select '192.168.1.100'::inet as ip union all
select '192.168.1.101'::inet union all
select '192.168.55.5'::inet union all
select '10.1.2.3'::inet;

create or replace view netblocks as
select '192.168.1.0/24'::cidr as nb union all
select '192.168.0.0/16'::cidr union all
select '10.0.0.0/8'::cidr union all
select '0.0.0.0/0'::cidr;

关于sql - 计算每个最小网络 block 的记录(间隔),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4378123/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com