With sql find next available integer within range that is not present in existing integer subset(s)

后端 未结 4 1148
谎友^
谎友^ 2021-02-07 12:02

Problem statement:

given a range x -> y of unsigned integers
where x and y are both in the range

4条回答
  •  北恋
    北恋 (楼主)
    2021-02-07 12:36

    After a lot of thinking, I believe a query as simple as this will do:

    with a as(
      -- next ip address
      select n.next_address, i.subnet_sk
      from ip_address i
      CROSS APPLY (SELECT convert(binary(4), convert(bigint, i.address) + 1) AS next_address) as n
      where n.next_address NOT IN (SELECT address FROM ip_address)
      AND EXISTS (SELECT 1 FROM subnet s WHERE s.subnet_sk = i.subnet_sk and n.next_address > s.ipv4_begin and n.next_address < s.ipv4_end)
    
      UNION -- use UNION here, not UNION ALL to remove duplicates
    
      -- first ip address for completely unassigned subnets
      SELECT next_address, subnet_sk
      FROM subnet 
      CROSS APPLY (SELECT convert(binary(4), convert(bigint, ipv4_begin) + 1) AS next_address) n
      where n.next_address NOT IN (SELECT address FROM ip_address)
    
      UNION -- use UNION here, not UNION ALL to remove duplicates
    
      -- next ip address from dhcp ranges
      SELECT next_address, subnet_sk
      FROM dhcp_range
      CROSS APPLY (SELECT convert(binary(4), convert(bigint, end_address) + 1) AS next_address) n
      where n.next_address NOT IN (SELECT address FROM ip_address)
    )
    SELECT min(next_address), subnet_sk
    FROM a WHERE NOT exists(SELECT 1 FROM dhcp_range dhcp
             WHERE a.subnet_sk = dhcp.subnet_sk and a.next_address
                between dhcp.begin_address
                    and dhcp.end_address)
    GROUP BY subnet_sk
    

    It is for IPV4, but can be easily extended for IPV6

    SQLFiddle

    Results for each subnet:

               subnet_sk
    ---------- -----------
    0xAC101129 1
    0xC0A81B1F 2
    0xC0A8160C 3
    
    (3 row(s) affected)
    

    In my opinion it should be very fast. Please check it

提交回复
热议问题