【问题标题】:How can I sort IP addresses in MySql, so ipv4 comes before ipv6 addresses?如何在 MySql 中对 IP 地址进行排序,所以 ipv4 排在 ipv6 地址之前?
【发布时间】:2020-02-17 01:56:40
【问题描述】:

我在 MySQL 中有一个表,其中有一列包含 ip 地址 - 存储为“VARCHAR(40)”。 ipv4 和 ipv6 地址都被使用了。

现在我想对这些地址进行排序,但我希望所有 ipv4 地址都排在所有 ipv6 地址之前。 我试过了:

ORDER BY INET6_ATON(IpAddress) 其中IpAddress 是列的名称。 INET6_ATON 返回一个 'VARBINARY(16)'。

排序会得到如下结果:

35.229.251.134
2405:204:900e:e66c::1441:48a1
37.9.113.28

其中 ipv4 和 ipv6 混合使用。这当然是因为 24(十六进制)是 36(十进制),介于 35 和 37 之间。

如何对 ip 地址进行排序,所以 ipv4 总是排在 ipv6 之前?

编辑:

我正在考虑使用“INET6_ATON”将列更改为“VARBINARY(16)”来存储值。这是否提供了更多可能性?

【问题讨论】:

    标签: mysql sql sql-order-by ip-address


    【解决方案1】:

    您可以查找.并将它们放在第一位:

    order by (ipaddress not like '%:%') desc,  -- ipv4 desc
             INET6_ATON(IpAddress)
    

    【讨论】:

    • 那不是把'::ffff:255.255.255.255'放在一切之前吗?
    • @PoulBak 。 . .问题中没有这样的例子。这是一个边缘案例。但我更改了答案以查找冒号而不是句点。
    【解决方案2】:

    这就是我想出的。首先我做了:

    ORDER BY LENGTH(INET6_ATON(ipAddress)) ASC, INET6_ATON(ipAddress) ASC
    

    这行得通,但当然不是很有效。

    然后我(最后)将该列转换为varbinary(16),在保存时使用INET6_ATON(或在使用DataTable 时使用.Net 的IPAddress.GetAddressBytes())。

    现在我可以简单地做:

    ORDER BY LENGTH(ipAddress) ASC, ipAddress ASC
    

    这是非常有效的。我现在让所有 ipv4 地址出现在所有 ipv6 地址之前。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-26
      • 2011-10-02
      • 2016-03-04
      • 1970-01-01
      • 1970-01-01
      • 2011-06-09
      • 2013-07-02
      相关资源
      最近更新 更多