1
votes

SQL Sort versions numériques + chaîne

Je dois trier une table par la colonne de version qui est une chaîne aléatoire + numérique (x.xx.xx). Par exemple ma table ressemble à:

SELECT * FROM t_plugins WHERE a_category = 'string' AND a_master_ig = 2
ORDER BY SUBSTRING_INDEX(SUBSTRING_INDEX(trim(a_name), " ", -1), ".", -1)```


et mon résultat a pour ressembler à:

string 1.14.4
string 1.14.3
string 1.14.2
string 1.14.1
string 1.11
string 1.10.2
string 1.10
string 1.9.4
string 1.9.2
string 1.9
string 1.8.8
string 1.8
string 1.4.6

mon sql actuel est

string 1.14.2
string 1.14.1
string 1.14
string 1.14.3
string 1.14.4
string 1.11
string 1.10
string 1.10.2
string 1.9
string 1.9.4
string 1.9.2
string 1.8
string 1.8.8
string 1.4.6


0 commentaires

3 Réponses :


1
votes

Quelque chose comme ça devrait fonctionner:

| a_name        |
| :------------ |
| string 1.14.4 |
| string 1.14.3 |
| string 1.14.2 |
| string 1.14.1 |
| string 1.14   |
| string 1.11   |
| string 1.10.2 |
| string 1.10   |
| string 1.9.4  |
| string 1.9.2  |
| string 1.9    |
| string 1.8.8  |
| string 1.8    |
| string 1.4.6  |

L'idée est de:

  • séparez la chaîne du numéro de version

  • isolez le premier chiffre du numéro de version (et convertissez-le en une valeur entière) et utilisez-le comme premier critère de tri

  • puis isolez la deuxième et la troisième partie, convertissez-les en valeur décimale et utilisez-la comme deuxième critère de tri

Démo sur DB Fiddle strong >:

order by
    cast(
        substring_index(
            substring_index(a_name, ' ', -1),
            '.', 
            1
         ) 
         as unsigned
    ) desc,
    cast(
        right(
            substring_index(a_name, ' ', -1),
            length(substring_index(a_name, ' ', -1)) 
                - locate('.', substring_index(a_name, ' ', -1))
        )
        as decimal(10, 5)
    ) desc


0 commentaires

0
votes

Je pense que c'est plus simple en utilisant la conversion implicite:

order by substring_index(a_name, '.', 1) + 0,
         substring_index(substring_index(a.name, '.', 2), '.', -1) + 0,
         substring_index(a_name, '.', -1) + 0


0 commentaires

0
votes

En supposant qu'il n'y ait pas d'espace dans votre "chaîne aléatoire", cela devrait vous donner le résultat que vous attendez.

select 
    *
from 
    your_table
order by 
    cast('/' + TRIM(SUBSTRING(your_version_col,CHARINDEX(' ', your_version_col),LEN(your_version_col)))  + '/' as hierarchyid) desc


0 commentaires