2016-08-19 90 views
0

我有以下问题:获取从Postgres的子网/掩码MAX和MIN IP

现在我有子网/掩码信息(例如192.168.1.0/255.255.255.0)的表..但我需要从该子网获得MAX和MIN IP:

192.168.1.0/192.168.1.255

我找到了这样的回答:

how to query for min or max inet/cidr with postgres

卜t将其看来:

network_smaller(INET,INET)network_larger(INET,INET)

不存在。即使使用谷歌搜索,我找不到这些功能的任何答案。

谢谢!

编辑:

版本信息:在x86_64-红帽Linux的GNU的

PostgreSQL的9.2.15,由GCC编译(GCC)4.8.5 20150623(红帽4.8.5-4 ),64位

回答

0

不要谷歌,只是尝试:

select network_smaller('192.168.0.9'::inet, '192.168.0.11'::inet); 

network_smaller 
----------------- 
192.168.0.9 
(1 row) 

Postgres有2600多个内部功能。它们中的大多数对于创建各种类型的操作符类都很有用。并非所有文档都在文档中描述,但它们都是可用的。

你可以在pg_catalog中使用pgAdmin III找到它们。你只需要设置选项:文件 - >选项 - > UI杂项 - >在树状视图中显示系统对象。


集合函数min(inet)max(inet)Postgres的9.5被引入:

with test(ip) as (
values 
    ('192.168.0.123'::inet), 
    ('192.168.0.12'), 
    ('192.168.0.1'), 
    ('192.168.0.125') 
) 
select max(ip), min(ip) 
from test; 

     max  |  min  
---------------+------------- 
192.168.0.125 | 192.168.0.1 
(1 row) 

参见骨料min(inet)是如何定义的(它可以在pg_catalog找到):

CREATE AGGREGATE min(inet) (
    SFUNC=network_smaller, 
    STYPE=inet, 
    SORTOP="<" 
); 

有关How to query for min or max inet/cidr with postgres的问题Postgres 9.4。在我的回答中,我建议使用功能network_smaller(inet, inet)network_larger(inet, inet)。我敢肯定,他们是为了创建集合函数min(inet)max(inet)而添加的,但由于某些原因(可能是疏忽),集合仅出现在Postgres 9.5中。

Postgres 9.2你可以创建自己的函数作为替代,例如,

create or replace function inet_larger(inet, inet) 
returns inet language sql as $$ 
    select case when network_gt($1, $2) then $1 else $2 end 
$$; 

create or replace function inet_smaller(inet, inet) 
returns inet language sql as $$ 
    select case when network_lt($1, $2) then $1 else $2 end 
$$; 
+0

好吧。我显然试过.. 错误:函数network_smaller(inet,inet)不存在 提示:没有函数匹配给定的名称和参数类型。您可能需要添加显式类型转换。 –

+0

只是一个问题。依靠这种无证的功能有多安全? –

+0

@PhilipCouling - 我们可以依靠内部功能吗?我认为,就所有运营商,索引,排序和大多数总计而言,都是基于它们的。 – klin

2

我不认为这个问题是相关的,无论如何你的需要。此处定义的最小值和最大值与用于查找表中最小/最大值的SQL min()max()函数相似,而不是子网中最小/最大值。

我通常不是依靠无证功能的粉丝。他们可能是安全的,但可能是不是我一般喜欢的词。

有记录在案的网络功能的页面在这里: https://www.postgresql.org/docs/current/static/functions-net.html

你需要将两个:

  • 民会network(inet)
  • 马克斯将broadcast(inet)

这是因为网络名称始终是范围内的“第一个”ip和b roadcast地址始终是范围内的“最后”ip。