Come ORDINARE DA versioni tipiche di versioni software come XYZ?


13

Data una tabella "Rilasci software":

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

Come posso produrre questo output?

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

Risposte:


22

Per produrre l'output desiderato, puoi semplicemente:

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

Si può lanciare un intero textarray in un integerarray (per ordinare 9prima 10).
Uno può ORDER BYarray tipi. È uguale all'ordinamento per ciascuno degli elementi. E gli array più corti vengono prima di quelli più lunghi con identica parte iniziale.

db <> violino qui
Vecchio SQL Fiddle.


1
Questo è fantastico In qualche modo, questo ordina i valori mancanti correttamente, senza dover specificare l'ordine dei null: (1.6.9 -> 1.7 -> 1.7.1), piuttosto che (1.6.9 -> 1.7.1 -> 1.7). Accettando questo.
Chris Betti,

2
Se hai a che fare con versioni Maven o versioni che possono contenere caratteri non numerici, puoi prima rimuovere i caratteri non numerici:string_to_array(regexp_replace(version, '[^0-9.]', '', 'g'), '.')::int[]
Samuel

Lo uso per trovare la versione massima e funziona benissimoSELECT 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

Se si prevedono più elementi nella stringa di versione, utilizzare solo più indici di array. Se l'indice non esiste, il risultato sarà nullo (ad es. v[10]Restituirà null)


Devi convertirli in numeri? Altrimenti mi aspetterei 10di essere tra 1e 2.
JNK,

Ciò è confermato dal tuo violino ...
JNK,

Cancellare il mio a favore di questo. string_to_array è molto più semplice di regex.
Chris Betti,

@JNK: ecco di cosa v[1]::intsi tratta. Lancia la stringa su un numero intero.
a_horse_with_no_name

L'unica modifica che farei al tuo SQL è l'ordine per. Suggerisco di eliminare desc e questo creerà il set di risultati che @Chris Betti sta cercando.
Dom

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.