8768 sujets

Développement web côté serveur, CMS

Bonjour,

Si un tableau calcul LibreOffice fait un tri croissant sur une colonne de cette façon :

_ccc
2bbb
aaaa
xxx_xxx
xxxxxx


une requête mysql ASC par défaut renvoie cet ordre :

2bbb
aaaa
xxxxxx
xxx_xxx
_ccc

J'ai essayé de trier le tableau avec les modes listés sur cette page :
https://www.php.net/manual/fr/function.asort.php
mais sans résultat.

Auriez-vous une astuce ?
Merci.
Modifié par Mizushima (29 Apr 2024 - 19:53)
Bonsoir. Quelque chose comme ceci peut-être ? :
SELECT nom_colonne
FROM nom_table
ORDER BY LOCATE('_', nom_colonne) DESC, LENGTH(nom_colonne), nom_colonne;
Merci Olivier C de me faire découvrir des nouveaux paramètres SQL.
Le résultat est que LENGTH(nom_colonne) tri par longueur de champ alors que je souhaite un tri alphanumérique avec le tiret du bas avant les lettres et chiffres.
ORDER BY LOCATE n'existe pas sous cette forme sur cette page :
https://sql.sh/cours/order-by
il existe bien un paramètre https://sql.sh/fonctions/locate mais qui ne semble pas avoir la fonction recherchée. Du coup ORDER BY LOCATE('_', nom_colonne) ne change pas l'ordre de tri des tirets du bas comme l'exemple donné :

2bbb
aaaa
xxxxxx
xxx_xxx
_ccc

Néanmoins merci de m'avoir fait découvrir ces fonction et d'approfondir le langage SQL.
Et en supprimant LENGTH() tout simplement ?
Nota bene : je n'ai pas testé, ma base de prédilection c'est PostgreSQL.
en supprimant LENGTH() il ne se passe rien de plus.

Du coup avec les petit moyens de ma petite connaissance, une solution serait de remplacer les tirets du bas par une occurrence de ixe 0 (zéro) qui serait du coup bien triés, puis de remplacer à l'inverse cette occurrence par un tiret du bas, comme :

$pseudo = '_zzzzz';
$pseudo = str_replace('_', '00000', $pseudo); // $pseudo devient '00000zzzzz'

ajouter $pseudo dans la table sous cette forme, puis après la requête SQL ORDER BY pseudo, faire l'inverse pour l'affichage dans la liste : $pseudo = str_replace('00000', '_', $pseudo); // $pseudo REdevient '_zzzzz'

Sauf si une autre idée lumineuse arrive, je ferai le test, et reviendrai vous dire.
Merci.
Modifié par Mizushima (29 Apr 2024 - 10:30)
En attendant une éventuelle autre solution, voici la bidouille que j'ai mise en place :
dans la table j'ai ajouté une colonne
`pseudo_tri`

puis dans le code PHP, avant d'insérer une entrée dans la table (INSERT INTO), je remplace les tirets du bas par une occurrence de 0 (zéro) de cette façon :
$pseudo_tri = str_replace('_', '000000', $pseudo); // 6 zéros devraient suffirent non ?

ensuite je fais les requêtes en triant sur cette nouvelle colonne :
"SELECT * FROM [TABLE] ORDER BY pseudo_tri"

ainsi les pseudo avec tiret du bas sont bien au-dessus des lettres et chiffres comme je le souhaite, comme l'exemple déjà cité plus haut :

_ccc
2bbb
aaaa
xxx_xxx
xxxxxx

Vous me direz si je dois [Marquer le sujet comme résolu] ou pas.
Merci.
Modifié par Mizushima (29 Apr 2024 - 20:26)
Bonsoir,

Je vais peut-être dire une bêtise, mais côté PHP, est-ce que vous avez essayé le tri naturel, avec natsort, strnatcmp, etc. par exemple ?
JE sais pas si ça existe côté MySQL/MariaDB, j'ai un doute.

Autre possibilité peut-être, c'est que pour que _ apparaisse avant 2, il faut le considérer comme un tiret, donc basiquement replace(texte, '_', '-')
Si, ça existe, et c'est même plus facile sur MySQL que sur PostgreSQL :
SELECT colonne1
FROM nom_table
ORDER BY colonne1 ASC NATURAL;

Effectivement, ça vaut peut être le coup d'y jeter un œil.
https://www.php.net/manual/fr/function.strnatcmp.php semble ne traiter que des comparaisons de chaînes.
$pseudo_tri = str_replace('_', '-', $pseudo);
fonctionne car le tiret du milieu est trié avant les chiffres, la colone `pseudo_tri` servira donc pour le tri, cela dit cela fonctionnerait tant que les pseudos ne contiennent jamais de tiret du milieu ce qui est le cas pour l'instant, je n'ai pas testé le cas où certain pseudo commenceraient par un tiret du milieu à l'origine, car LibreOffice calc trie le _ avant le -.
ORDER BY colonne1 ASC NATURAL;
ne fonctionne pas sous mysql.db aucune donnée n'est récupérée.
cette page https://sql.sh/cours/order-by ne parle pas d'autres paramètres que
ORDER BY DESC
ORDER BY ASC
cette autre page (EN) dit des choses que je ne suis pas sûr de comprendre ou du moins qui me semble trop compliquées pour mes connaissances :
https://www.mysqltutorial.org/mysql-basics/mysql-natural-sorting/
Modifié par Mizushima (02 May 2024 - 19:26)