Bonjour,

J'ai une requête sql qui trie des données suivants le le nom (Zone1A, Zone2A, Zone3A, Zone 3B ...)


public function allZones(){
    return $this->sql("
      SELECT plantsubzones.*,plantzones.description As zonedescription
      FROM plantsubzones
      LEFT JOIN plantzones ON plantzones.id = plantsubzones.plantzone_id
      ORDER BY plantsubzones.subzonename
    
      ");
    }  


Le classement me mets Zone10A avant Zone1A.

Comment remédier à cela.

Merci d'avance
Salut Smiley smile

C'est tout à fait normal : la colonne subzonename est de type texte, le classement effectué dessus sera donc alphabétique.

SQL permet par exemple de convertir les types d'une colonne avec la fonction CAST(), mais le problème ici, c'est que cette colonne semble contenir elle-même plusieurs types de données :

- Le mot "Zone"
- Suivi de son numéro de sous-zone
- Suivi d'une lettre, probablement en rapport avec la zone parente

Je pense que cette colonne contient trop d'infos, qui à mon sens devraient plutôt être chacune enregistrées indépendamment dans d'autres colonnes.

Est-ce que le mot "Zone" est nécessaire et doit être enregistré systématiquement en base de données ? Le nom de la table fait déjà clairement référence à des zones. Si tu en as besoin pour l'affichage, pourquoi ne pas l'ajouter au niveau du code de ton application plutôt ?

Sans voir ton modèle relationnel, je pense deviner ici que tu disposes de deux tables : une pour les zones, une autre pour les sous-zones, une zone pouvant être liée à de multiples sous-zones, mais une sous-zone ne peut être liée qu'à une seule zone parente.

On pourra imaginer dans ce cas enregistrer la "lettre" d'une zone (A, B, C, etc.) au niveau de la table plantzone, et le numéro de sous-zone au niveau de la plantsubzone.

Ça donnerait ceci par exemple :

upload/1676748175-68566-plantzones.drawio2.png

Tu pourrais alors remanier ta requête SQL pour obtenir l'ordre dont tu as besoin, et en plus, tes données seront intègres :
SELECT plantsubzones.*, plantzones.lettre, plantzones.description As zonedescription
FROM plantsubzones
LEFT JOIN plantzones ON plantzones.id_zone = plantsubzones.id_zone
ORDER BY plantsubzones.numéro, plantzones.lettre ASC

Si tu as la possibilité de faire cette modification au niveau de ton modèle de données, je pense que c'est la solution la plus propre.

Il existerait sinon d'autres techniques qui consisteraient à ajouter de la logique au niveau de ta requête, pour "extraire" les valeurs de ta colonne "name", mais c'est pas vraiment propre et recommandé, et ça fait beaucoup de responsabilités pour une requête SQL dont le rôle ne devrait être "que" de te rendre des données Smiley smile
Modifié par Loraga (18 Feb 2023 - 20:22)
Merci beaucoup Loraga pour ta réponse, je vais regarder cela de près.

C'est vrai que d'avoir Zone dans les noms ne s'imposait pas.