Tri des résultats ORDER BY

WRInaute occasionnel
Bonjour,

Si j'ai une table contenant les mots suivants :

poire
banane
orange
melon
pomme

Y a-t-il une possibilité d'indiquer dans le ORDER BY (ou ailleurs) que je souhaite afficher (trier et/ou grouper) d'abord toutes les orange, puis toutes les banane, puis toutes les poire, etc... ? Bref de pouvoir trier les mots de ma table dans l'ordre que je souhaite. Je ne souhaite pas faire un tri alphabétique car ça je sais faire avec le "order by".

Merci pour vos réponses.
 
WRInaute occasionnel
Code:
ORDER BY poire, banane, orange, melon, pomme

Tu les mets dans l'odre de ton choix c'est tout simple ^^
 
WRInaute occasionnel
Merci amokk mais comment fais-tu pour indiquer dans ton "order by" que ces mots proviennent du champs "fruits" et pas des autres champs "arbres", "legumes", etc... ?

Ma table a 25 champs différents !

Il faudrait faire une requête du style ORDER BY fruits[pomme],fruits[banane], etc... mais ça ca ne marche pas !
 
WRInaute occasionnel
Code:
SELECT * FROM fruits ORDER BY poire, banane, orange, melon, pomme

* = tous
Fruits = nom de ta colonne "fruits" 8)
 
WRInaute accro
toto2525 a dit:
Si j'ai une table contenant les mots suivants :

poire
banane
orange
melon
pomme
Tu veux dire une table dont une colonne peut prendre les valeurs en question?

toto2525 a dit:
Y a-t-il une possibilité d'indiquer dans le ORDER BY (ou ailleurs) que je souhaite afficher (trier et/ou grouper) d'abord toutes les orange, puis toutes les banane, puis toutes les poire, etc... ? Bref de pouvoir trier les mots de ma table dans l'ordre que je souhaite. Je ne souhaite pas faire un tri alphabétique car ça je sais faire avec le "order by".

A ma connaissance, pas directement. Plusieurs solutions:
- tu ajoutes une colonne "ordre_de_tri", et tu mets 1 dedans pour toutes les lignes qui ont la valeur "orange", 2 pour "banane", etc. Ensuite tu tries (ORDER BY) en utilisant cette colonne.

- tu crées une nouvelle table "tri_des_fruits", avec deux colonnes, "nom_fruit", "ordre_de_tri". Tu devines comment tu la remplis, et ensuite au moment de ton select tu fais une jointure avec cette table (SELECT ... FROM table,tri_des_fruits WHERE fruit=nom_fruit ORDER BY ordre_de_tri).

- la meilleure solution: tu crées une nouvelle table "fruits", avec trois colonnes: "id", "nom", "ordre_de_tri". ID est un truc genre SERIAL ou je ne sais pas comment ça s'appelle en mysql (une valeur unique qui s'auto-incrémente). Tu remplis la table, puis dans l'autre table tu remplaces la colonne "fruit" d'origine par une autre colonne qui contient l'ID du fruit. Ensuite tu fais comme dans le cas précédent (jointure).

Pourquoi la dernière solution est-elle la meilleure? Parce qu'elle consiste à "normaliser" ta table. Ca permet de limiter l'espace de stockage utilisé pour stocker le nom du fruit en clair (un ID qui va en général faire 4 octets c'est toujours moins qu'une chaîne, et c'est plus rapide à traiter en plus), ça permet d'éviter les erreurs qui se glisseraient ("piore", "bannane"...), ça permet de modifier facilement tout un tas de monde (il suffit de modifier une ligne de la liste des fruits), ça permet de gérer plus facilement des choses comme des traductions, ça permet de réutiliser la même liste dans plusieurs tables sans avoir d'incohérences, ça permet d'avoir facilement une liste des fruits (pour faire une saisie avec un liste par exemple), et j'en passe...

Sinon en mysql il y a peut-être un moyen d'utiliser des "enums", mais je n'en sais trop rien.

Hop,

Jacques.
 
WRInaute occasionnel
Merci pour vos réponses.

Le souci c'est que dans cette table il y a à peu près 20 champs (colonnes) différentes et que cette table a environ 50 000 entrées (lignes), ça va être dur de recréer une nouvelle table pour les données à trier d'autant plus que je vais avoir besoin de trier dans un certain ordre au moins 4 ou 5 de ces champs (colonnes), je pensais qu'il y avait une solution avec le ORDER BY !

Je pensais ajouter une lettre devant le nom des fruits qui correspondrait à l'ordre dans lequel je souhaite trier ces mots, par exemple si je souhaite que "pomme" soit afficher le premier de ma liste lorsque je trierai mes données, j'ajoute "apomme" (je remplace "pomme" par "apomme") si je veux que fraise soit le deuxième j'ajoute "bfraise" et si je veux que banane soit le troisième j'ajoute "cbanane" et comme cela avec un banale "ORDER BY fruits" fruits étant le nom du champ ou sont stockés "banane", "poire", "pomme", etc... on peut trier comme on veux... c'est un peu lourd comme sytsème mais ça marche !

Avez-vous une autre solution ?
 
WRInaute occasionnel
Je crois pas que tu puisses faire cela avec clause Groupe By et Order BY car tu vas trier en fonction du nom d'un champ (de la colonne "fruits" par exemple) mais tu ne triera pas en fonction des mots qui sont stockés dans le champ "fruits" !

Comment tu vas dire dans ta clause Groupe By et Order BY ah non là tu ordonnes tes résultats d'abord en fonction du mot "poire", ensuite le mot "banane" et puis le mot "fraise" ?
 
WRInaute passionné
Avez-vous une autre solution ?

bah non,

a partir du moment ou in n'y a pas d'algo de tri correspondant à celui que tu veux appliquer

il va falloir le créer et jcaron t'a donné les solutions traditionnelles à ton problème

soit tu ajoute un champs pour indexer tes fruits avec ton ordre de tri

soit tu crées une table fruit avec un id_tri qui va correspondre avec ton ordre de tri et va inserer ce id_tri dans ton champs fruit de ta table initiale

je sais je repete exactement ce que jcaron a dit par contre les manips sont rapides, c'est un update where champs like, une requete par fruit et c'est réglé

lol

rog
 
WRInaute accro
toto2525 a dit:
Le souci c'est que dans cette table il y a à peu près 20 champs (colonnes) différentes et que cette table a environ 50 000 entrées (lignes), ça va être dur de recréer une nouvelle table pour les données à trier d'autant plus que je vais avoir besoin de trier dans un certain ordre au moins 4 ou 5 de ces champs (colonnes)

Bah, ça va vite (je le fais en syntaxe postgresql, il peut y avoir quelques modifs à faire pour que ça passe avec mysql):

Code:
create table fruits (id serial primary key,name text,sort integer);
insert into fruits select default,fruit from table_originale group by fruit;
update fruits set sort=100 where name='orange';
update fruits set sort=200 where name='banane';
update fruits set sort=300 where name='poire';
[...]
alter table table_originale add column idfruit integer not null references fruits(id);
update table_originale set idfruit=(select id from fruits where name=fruit);
alter table table_originale drop column fruit;
select * from table_originale t join fruits f on t.idfruit=f.id order by f.sort;

Ca se réplique avec autant de tables que tu veux...

toto2525 a dit:
Je pensais ajouter une lettre devant le nom des fruits qui correspondrait à l'ordre dans lequel je souhaite trier ces mots, par exemple si je souhaite que "pomme" soit afficher le premier de ma liste lorsque je trierai mes données, j'ajoute "apomme" (je remplace "pomme" par "apomme") si je veux que fraise soit le deuxième j'ajoute "bfraise" et si je veux que banane soit le troisième j'ajoute "cbanane" et comme cela avec un banale "ORDER BY fruits" fruits étant le nom du champ ou sont stockés "banane", "poire", "pomme", etc... on peut trier comme on veux... c'est un peu lourd comme sytsème mais ça marche !

Super pratique quand tu vas vouloir changer l'ordre de tri, ou ajouter une nouvelle valeur "entre" deux valeurs existantes. Je ne te parle même pas de la façon dont tu vas gérer les insertions de nouvelles lignes dans ta table...

Sérieusement, quel est le problème avec la normalisation de la table? Sur une table de 50 000 lignes, tu vas clairement y gagner de tous points de vue... Ceci dit, si tu pars dans cette direction:
- la méthode qui consiste à ajouter une colonne à ta table est probablement nettement plus simple et pratique (mais à long terme reste nettement moins pratique que la normalisation de la table)
- utilise plutôt des chiffres que des lettres, et mets en plus d'un, et prévois "de la place" entre des valeurs successives. Genre au lieu de "aorange", "bbanane"... utilise "100_orange", "200_banane"...

Jacques.
 
WRInaute occasionnel
Merci pour vos réponses.

Je crois que je vais suivre tes recommandations jcaron et utiliser plutôt des chiffres que des lettres, car ma table sera mise à jour entièrement toutes les semaines, donc je me vois mal créer une nouvelle table pour chaque colonne que je souhaite trier chaque mise à jour, je crois qu'il est plus simple de créer ma table normalement et ensuite je fais un update sur les mots que je souhaite changer, du style :

UPDATE ma_table SET fruits='100_pomme' WHERE fruits='pomme'
 
Discussions similaires
Haut