Postgresql-查找INET范围内的第一个缺口
我有以下用于存储IPs PostgreSQL的表结构: 如何找到127.0.0.2,因为它是下一个免费的最低IP 我有点被困在如何以优化的方式处理这个问题上 这似乎可以做到这一点,但这是一种降低子网大小/10 4M+记录速度的方法:Postgresql-查找INET范围内的第一个缺口,sql,postgresql,Sql,Postgresql,我有以下用于存储IPs PostgreSQL的表结构: 如何找到127.0.0.2,因为它是下一个免费的最低IP 我有点被困在如何以优化的方式处理这个问题上 这似乎可以做到这一点,但这是一种降低子网大小/10 4M+记录速度的方法: SELECT sub.ip FROM (SELECT set_masklen(((generate_series(1, (2 ^ (32 - masklen('127.0.0.0/10'::cidr)))::integer - 2) + '127.0.0.0/10'
SELECT sub.ip FROM
(SELECT set_masklen(((generate_series(1, (2 ^ (32 - masklen('127.0.0.0/10'::cidr)))::integer - 2) + '127.0.0.0/10'::cidr)::inet), 32) as ip) AS sub
WHERE sub.ip NOT IN
(SELECT ip from ips)
AND sub.ip > set_masklen('127.0.0.0/10', 32)
AND sub.ip < set_masklen(broadcast('127.0.0.0/10')::inet, 32)
ORDER BY ip ASC LIMIT 1;
您可以使用以下功能:
select ips.ip + 1
from ips
where not exists (select 1 from ips ips2 where ips2.ip = ips.ip + 1)
order by ips.ip
limit 1;
如果使用9.3或更新版本,则可以利用横向连接
SELECT (a.ip+1) as low, q.ip as high FROM ips a LEFT JOIN LATERAL
(SELECT * FROM ips b WHERE a.ip < b.ip ORDER BY b.ip ASC limit 1) AS q ON true
WHERE q.ip <> (a.ip + 1) LIMIT 1;
使用正确的筛选器和顺序连接同一个表,然后使用ip+1为每一行生成下一个数字,并检查其是否匹配。将结果限制为第一个。为什么将q.ip返回为高?作为参考,这样您就可以看到发生了什么。思考最后一个q.ip a.ip+1的位置应该是低asc的q.ip a.ip+1的位置。
SELECT (a.ip+1) as low, q.ip as high FROM ips a LEFT JOIN LATERAL
(SELECT * FROM ips b WHERE a.ip < b.ip ORDER BY b.ip ASC limit 1) AS q ON true
WHERE q.ip <> (a.ip + 1) LIMIT 1;