Tuesday, May 3, 2016

PostgreSQL: select ip range with max masklen

            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);