如何按典型软件发行版(例如XYZ)订购?


13

给定一个“ SoftwareReleases”表:

| id | version |
|  1 | 0.9     |
|  2 | 1.0     |
|  3 | 0.9.1   |
|  4 | 1.1     |
|  5 | 0.9.9   |
|  6 | 0.9.10  |

如何产生此输出?

| id | version |
|  1 | 0.9     |
|  3 | 0.9.1   |
|  5 | 0.9.9   |
|  6 | 0.9.10  |
|  2 | 1.0     |
|  4 | 1.1     |

Answers:


22

要产生所需的输出,您可以简单地:

SELECT id, version
FROM   versions
ORDER  BY string_to_array(version, '.')::int[];

可以将整个text数组转换为integer数组(在9之前排序10)。
一个可以ORDER BY数组类型。这与每个元素的排序相同。较短的阵列排在较长的阵列之前,而前排具有相同的引导部分。

db <> fiddle 这里是
旧的SQL Fiddle。


1
这很棒。不知何故,这可以正确地对缺失值进行排序,而不必指定null的顺序:(1.6.9-> 1.7-> 1.7.1),而不是(1.6.9-> 1.7.1-> 1.7)。接受这一点。
克里斯·贝蒂

2
如果您正在处理Maven版本或可能包含非数字字符的版本,则可以先删除非数字字符:string_to_array(regexp_replace(version, '[^0-9.]', '', 'g'), '.')::int[]
Samuel

我用它来查找最高版本,效果很好SELECT max(string_to_array(build_version, '.')::int[]
Joviano Dias

6
select id,
       name, 
       v[1] as major_version,
       v[2] as minor_version,
       v[3] as patch_level
from (
   select id, 
          name, 
          string_to_array(version, '.') as v
   from versions
) t
order by v[1]::int desc, v[2]::int desc, v[3]::int desc;

SQLFiddle:http ://sqlfiddle.com/#!15/c9acb/1

如果您希望版本字符串中包含更多元素,则只需使用更多数组索引即可。如果索引不存在,则结果将为null(例如,v[10]将返回null


您需要将它们转换为数字吗?否则,我期望10介于1和之间2
JNK

您的小提琴证实了这一点……
JNK 2014年

为此删除我的。string_to_array比正则表达式简单得多。
克里斯·贝蒂

@JNK:就是这样v[1]::int。它将字符串转换为整数。
a_horse_with_no_name 2014年

我对您的SQL所做的唯一更改是排序依据。我建议取出desc,这将创建@Chris Betti寻找的结果集。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.