【问题标题】:Aggregate function for inet values in Postgres?Postgres中inet值的聚合函数?
【发布时间】:2020-12-15 14:59:21
【问题描述】:

我有如下数据:

addr
10.0.0.0/32
10.0.0.1/32
10.0.0.2/32
10.0.0.3/32
10.0.0.4/32
10.0.0.5/32
10.0.0.6/32
10.0.0.7/32

我想做这样的事情:

select agg_inets(addr) as supernets from addr_table

然后得到:

supernets
10.0.0.0/29

在另一个示例中,数据可能不包含连续地址,在这种情况下,我希望获取 CIDR 范围的记录集:

addr
10.0.0.0/32
10.0.0.4/32
10.0.0.5/32
10.0.0.6/32
10.0.0.7/32

结果:

10.0.0.0/32
10.0.0.4/30

似乎没有任何内置函数可以实现这一点。我还有其他选择吗?

【问题讨论】:

    标签: sql postgresql aggregate-functions


    【解决方案1】:

    demo:db<>fiddle

    我没有发现任何内置函数,但有一个名为 inet_merge(inet, inet) (Docs) 的函数可用于自定义聚合函数:

    CREATE AGGREGATE agg_inets (inet) (
        sfunc =  inet_merge,
        stype =  cidr,
        initcond = '10.0.0.0/32');
    

    【讨论】:

    • 这看起来不错,虽然initcond有什么意义?我必须提前知道最小值并确保我的 inet 地址是连续的吗?如果我的所有记录都不是通过返回多个最小大小的 cidr 连续的 inet 地址,这可以工作吗?
    • 能否将您的用例添加到您的问题中,以便我们进行检查。 initcond 有必要告诉 agg 函数应该根据第一条记录检查的值是什么。也许有办法避免这种情况
    • 您不需要最少的数据,您需要最少的网络范围。即使您的数据中没有 10.0.0.0,它也可以工作:dbfiddle.uk/…
    • 谢谢,很抱歉造成混淆 - 在我的用例中,返回暗示某些地址在输入记录集中的 CIDR 是无效的。我添加了另一个示例!
    • 也许是这个? dbfiddle.uk/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-25
    • 2011-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-13
    • 1970-01-01
    相关资源
    最近更新 更多