Tuesday, May 3, 2016

PostgreSQL: select ip range with max masklen

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
with
radius_cdr_pdp(sgsn_address, cdr_src_id) as (
    values ('212.183.144.0'::inet, 1), ('212.183.144.0'::inet, 2), (null, 3)
),
dt_ip_range(ip_range) as (
    values ('212.183.144.0/16'::inet), ('212.183.144.0/24'::inet), ('212.182.0.0/16'::inet), (null)
),
radius_cdr_pdp_max as (
    select max(masklen(dt_ip_range.ip_range)) as max_masklen, cdr_src_id
    from radius_cdr_pdp
    left join dt_ip_range on radius_cdr_pdp.sgsn_address <<= dt_ip_range.ip_range
    group by cdr_src_id
)
select radius_cdr_pdp.sgsn_address, dt_ip_range.ip_range, radius_cdr_pdp.cdr_src_id, radius_cdr_pdp_max.max_masklen
from radius_cdr_pdp
join radius_cdr_pdp_max using (cdr_src_id)
left join dt_ip_range
    on radius_cdr_pdp.sgsn_address <<= dt_ip_range.ip_range
    and radius_cdr_pdp_max.max_masklen = masklen(dt_ip_range.ip_range);