Jak zamówić według typowych wersji oprogramowania, takich jak XYZ?

13

Biorąc pod uwagę tabelę „SoftwareReleases”:

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

Jak wygenerować ten wynik?

| 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
źródło

Odpowiedzi:

22

Aby uzyskać pożądany wynik, możesz po prostu:

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

Można rzucić całą texttablicę na integertablicę (do sortowania 9wcześniej 10).
Można ORDER BYtablicować typy. Jest to to samo, co porządkowanie według każdego z elementów. A krótsze tablice pojawiają się przed dłuższymi z identyczną wiodącą częścią.

db <> skrzypce tutaj
Old SQL Fiddle.

Erwin Brandstetter
źródło
1
To jest świetne. Jakoś to porządkuje brakujące wartości poprawnie, bez konieczności określania kolejności null: (1.6.9 -> 1.7 -> 1.7.1), zamiast (1.6.9 -> 1.7.1 -> 1.7). Zaakceptowanie tego.
Chris Betti,
2
Jeśli masz do czynienia z wersjami Maven lub wersjami, które mogą zawierać znaki nienumeryczne, możesz najpierw usunąć znaki nienumeryczne:string_to_array(regexp_replace(version, '[^0-9.]', '', 'g'), '.')::int[]
Samuel
Używam tego, aby znaleźć wersję maksymalną i działa świetnieSELECT 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

Jeśli oczekujesz więcej elementów w łańcuchu wersji, po prostu użyj więcej indeksów tablic. Jeśli indeks nie istnieje, wynik będzie pusty (np. v[10]Zwróci null)

koń bez imienia
źródło
Czy chcesz je przekonwertować na liczby? W przeciwnym razie spodziewałbym 10się pomiędzy 1i 2.
JNK
Potwierdza to twoje skrzypce ...
JNK
Usunięcie mojego na korzyść tego. string_to_array jest znacznie prostszy niż regex.
Chris Betti
@JNK: o to właśnie v[1]::intchodzi. Rzuca ciąg na liczbę całkowitą.
a_horse_w_no_name
Jedyną zmianą, którą dokonam w twoim SQL, jest kolejność. Proponuję wyjąć desc, a to utworzy zestaw wyników, którego szuka @Chris Betti.
niedz.