【问题标题】:sort / order by software version - algorithm/implementation按软件版本排序/排序 - 算法/实现
【发布时间】:2011-10-26 00:21:37
【问题描述】:

我正在寻找一种方法来对一组定义软件版本的字符串进行排序/排序,格式如下:x.x.x(例如:1.3.12)。

这些字符串在数据库(mysql)中,但我不确定这是否相关。

我能想到的一个想法是进行字符串 -> 整数(或浮点数)转换,然后按整数索引对集合进行排序。但是我不确定这是否可能。

我也在寻找其他想法。

谢谢

更新:我只是想设置一个代表我可以实现的最大版本的数字(版本是指主要版本、次要版本、修订版)。例如我选择数字 300 ,所以最大版本为 299.299.299 所以..当我转换我可以做这样的事情:major*pow(300,2)+minor*pow(300,1)+revision*pow(300,0)

仍然对想法持开放态度。

【问题讨论】:

    标签: mysql database sorting version-control version


    【解决方案1】:

    不要将多点字符串用作字符串 - 比较它的值会让人头疼

    在您的情况下,您可以(必须?)将版本扩展为 4 字节字符串(尾随 0)并使用 IP4 相关函数(来自前端或内置 MySQL)

    来自MySQL manual

    INET_ATON(expr)

    鉴于 IPv4 网络地址的点分四元组表示为 字符串,返回一个整数,表示 网络字节顺序(大端)的地址。 INET_ATON() 返回 NULL 如果它不理解它的论点。

    mysql> SELECT INET_ATON('10.0.5.9'); -> 167773449

    对于本例,返回值计算为 10×2563 + 0×2562 + 5×256 + 9。

    INET_ATON() 可能会或可能不会返回短格式 IP 的非 NULL 结果 地址(例如“127.1”作为“127.0.0.1”的表示)。 因此,INET_ATON()a 不应用于此类地址。

    注意:

    要存储由 INET_ATON() 生成的值,请使用 INT UNSIGNED 列 而不是已签名的 INT。如果您使用有符号列,则值 对应于第一个八位字节更大的 IP 地址 超过 127 无法正确存储。请参见第 10.6 节,“超出范围 和溢出处理”。

    INET_NTOA(expr)

    给定一个按网络字节顺序排列的数字 IPv4 网络地址,返回 地址的点分四进制表示为二进制字符串。 如果 INET_NTOA() 不理解其参数,则返回 NULL。

    【讨论】:

    • 当有数字时,可以使用MAX()等数字函数和操作数
    【解决方案2】:

    我只能给出没有语言的伪代码,但是...使用 mysql 中的 SUBSTRING_INDEX() 或另一种语言中的类似函数来使用 .为分隔符。然后使用一组嵌套的 if..then 条件来比较字符串,如

    if(substr1<substr2) return str2;
    elseif(subrtr1>substr2) return str1;
    elseif(substr1 = substr2)
      if(substr1b<substr2b) return str2;
      elseif(subrtr1b>substr2b) return str1;
      elseif(substr1b = substr2b)
    

    等等……

    堆是另一种实现方式。将比较定义为 compare() 函数。然后添加值并让堆对它们进行排序。

    【讨论】:

      【解决方案3】:

      遇到同样的问题,我最终得到了类似情况的以下解决方案:

      select *
      from Softwareedition
      order by Softwareedition.IsMostRecentVersion DESC,
      INET_ATON(
          CASE (LENGTH(Softwareedition.VersionNumber) - LENGTH(REPLACE(Softwareedition.VersionNumber, ".", "")))
              WHEN 1 then concat(Softwareedition.VersionNumber,".0.0")
              WHEN 2 then concat(Softwareedition.VersionNumber,".0")
              ELSE Softwareedition.VersionNumber
          END) DESC,
      Softwareedition.Name DESC
      

      【讨论】:

        【解决方案4】:

        您可以将这些值存储为 VARCHAR 或 CHAR 然后只需在查询末尾添加 ORDER BY ... DESC 即可在顶部获取最新版本或省略 DESC 部分(无论如何 MySQL 默认为 ASC)在顶部获取最早的版本

        伪代码:

        SELECT * FROM Table WHERE xxx ORDER BY Version DESC
        

        【讨论】:

        • 那么'2.2.2'会排在'10.10.10'之后
        • 你的表结构是什么?您可以将字段分为主要版本和次要版本吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-30
        • 1970-01-01
        • 1970-01-01
        • 2013-02-02
        相关资源
        最近更新 更多