Comment COMMANDER PAR des versions de version de logiciel typiques comme XYZ?


13

Étant donné un tableau "SoftwareReleases":

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

Comment puis-je produire cette sortie?

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

Réponses:


22

Pour produire la sortie souhaitée, vous pouvez simplement:

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

On peut convertir un texttableau entier en un integertableau (pour trier 9avant 10).
On peut ORDER BYgrouper des types. C'est la même chose que la commande par chacun des éléments. Et les tableaux plus courts passent avant les tableaux plus longs avec une partie principale identique.

db <> violon ici
Old SQL Fiddle.


1
C'est bien. D'une certaine manière, cela trie correctement les valeurs manquantes, sans avoir à spécifier l'ordre des valeurs nulles: (1.6.9 -> 1.7 -> 1.7.1), plutôt que (1.6.9 -> 1.7.1 -> 1.7). Accepter celui-ci.
Chris Betti

2
Si vous avez affaire à des versions de Maven ou à des versions pouvant contenir des caractères non numériques, vous pouvez d'abord supprimer les caractères non numériques:string_to_array(regexp_replace(version, '[^0-9.]', '', 'g'), '.')::int[]
Samuel

Je l'utilise pour trouver la version maximale et cela fonctionne très bienSELECT 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

Si vous attendez plus d'éléments dans la chaîne de version, utilisez simplement plus d'index de tableau. Si l'index n'existe pas, le résultat sera nul (par exemple v[10]retournera null)


Avez-vous besoin de les convertir en nombres? Sinon, je m'attendrais 10à être entre 1et 2.
JNK

Ceci est confirmé par votre violon ...
JNK

Supprimer le mien en faveur de cela. string_to_array est beaucoup plus simple que regex.
Chris Betti

@JNK: c'est de cela qu'il v[1]::ints'agit. Il convertit la chaîne en un entier.
a_horse_with_no_name

La seule modification que j'apporterais à votre SQL est la commande par. Je suggère de supprimer desc et cela créera le jeu de résultats recherché par @Chris Betti.
Dim

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.