Como encomendar versões típicas de lançamento de software como XYZ?

13

Dada uma tabela "SoftwareReleases":

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

Como produzo essa saída?

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

Respostas:

22

Para produzir a saída desejada, você pode simplesmente:

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

Pode-se converter uma textmatriz inteira em uma integermatriz (para classificar 9antes 10).
Pode-se ORDER BYordenar tipos. É o mesmo que ordenar por cada um dos elementos. E matrizes mais curtas vêm antes das matrizes mais longas com a parte principal idêntica.

db <> fiddle aqui
Old SQL Fiddle.

Erwin Brandstetter
fonte
11
Isso é ótimo. De alguma forma, isso classifica os valores ausentes corretamente, sem precisar especificar a ordem dos nulos: (1.6.9 -> 1.7 -> 1.7.1), em vez de (1.6.9 -> 1.7.1 -> 1.7). Aceitando este.
Chris Betti
2
Se você estiver lidando com versões do Maven ou versões que podem conter caracteres não numéricos, remova primeiro os caracteres não numéricos:string_to_array(regexp_replace(version, '[^0-9.]', '', 'g'), '.')::int[]
Samuel
Eu uso isso para encontrar a versão Max e ele funciona muito bemSELECT 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 você espera mais elementos na cadeia de versão, use apenas mais índices de matriz. Se o índice não existir, o resultado será nulo (por exemplo v[10], retornará null)

um cavalo sem nome
fonte
Você precisa convertê-los em números? Caso contrário, eu esperaria 10estar entre 1e 2.
JNK
Isto é confirmado por seu violino ...
JNK
Excluindo o meu em favor disso. string_to_array é muito mais simples que regex.
22814 Chris Betti
@ JNK: é disso que v[1]::intse trata. Ele lança a string para um número inteiro.
A_horse_with_no_name
A única alteração que eu faria no seu SQL é a ordem de. Sugiro remover o desc e isso criará o conjunto de resultados que @Chris Betti está procurando.
Sun