SQL avancé : Définir un orde de tri pour ORDER BY

Bonjour à tous

Je cherche à trier des données, dans un ordre spécifique. Par exemple, je voudrais trier des données par région, mais en mettant Europe avant Asie au lieu du tri alphabétique conventionnel.

En cherchant un peu sur google, je suis tombé sur ce genre de trucs, mais ca ne fonctionne pas, et je ne sais pas trop comment ca marche :

ORDER BY region when 'E' then 1 when 'A' then 2 else 3 end

Soit tu ajoutes une nouvelle colonne avec l’ordre réel dans le quel tu veux l’afficher (Europe, 1; Asie, 2; reste, 3) et tu fais ton ORDER BY NouvelleColonne, region ou alors tu fais la meme chose mais dans le query (en utilisant CASE comme dans ton example).

Voila un example complet:

Select * From dbo.MyTable
Order by 
	CASE MyUDT 
		WHEN 'Record 1' 
			THEN 1 
		Else 2 
		END asc, 
	MyUDT desc

La table MyTable a une colonne (MyUDT) contenant Record 1, Record 2 et Record 3.
Avec cette query il va afficher Record 1 en premier et le reste par ordre alphabetique inverse (je hais la langue francaise … Descending en anglais :slight_smile: )

La solution facile et pas chere c’est d’ajouter a ta query la logique de l’exemple, mais chaque mise a jour ou modification du code prendra du temps.
La vrai bonne solution c’est de rajouter une colonne a ta table pour un ordre de tri specifique (t’auras plus jamais a toucher ton code/query).

Pour mon exemple j’aurai pu ajouter une colonne:
Record 1 1
Record 2 2
Record 3 2

Et faire une simple query:

Select * From dbo.MyTable
Order by MyNewColumn asc, MyUDT Desc

Edité le 26/08/2009 à 13:22

Waw merci pour cette super réponse.
D’après ce que j’ai compris, tu conseilles de rajouter un champs à ma table, et de indiquer les differentes valeurs de tri à tous mes objets? C’est sur que c’est efficace… mais j’ai plus de 200 objets a modifier alors =/

Je pense que la methode de tri par requete est beaucoup plus facile, et je suis sur de jamais devoir modifier quoi que ce soit apres :wink:
Je vais essayer le premier code que tu as fourni. Je te tiens au courant si j’ai reussi à l’adapter :wink:

Merci

EDIT : J’ai essayer ton code, ca marche super nikel :smiley:

Order by CASE region WHEN 'Europe' THEN 1 Else 2 END ASC

Edité le 26/08/2009 à 13:37

En fait tu ne dois pas mettre a jour toutes les lignes, tu les mets par exemple toutes a 50, celle qui doivent avoir une plus grand priorité tu leur donne un numero specifique plus petit et si tu en veux a la fin tu leur donne un numero plus grand.

Il me semble meme que si tu ne modifies que les clignes que tu veux changer (en laissant les autres a NULL) ca devrai aussi marcher (je crois bien que NULL arrive a la fin dans un ORDER BY xxx).

Avec cette solution tu peux meme faire des choses plus precise, par exemple tu pourrais avoir une liste de pays, mettre en premier l’europe, puis l’asie, puis tout les payes de l’europe par ordre alphabetique et puis le reste des pays du monde:

Allemagne 3
Asie 2
Belgique 3
Canada 4
Europe 1
France 3
Italie 3
USA 4

Le resultat serai:
Europe
Asie
Allemagne
Belgique
France
Italie
Canada
USA
Edité le 26/08/2009 à 14:57

Ah oaui cest pas bête non plus.
Pour le moment je fais mon ordre de tri avec les WHEN, THEN… Mais c’est vrai que quand on veut idiquer plusieurs ordres la requete deviens vite tres longue.

Mais pas sur que jaurai moin de boulot en rajoutant un champ de tri :stuck_out_tongue:
En tout cas j’ai plusieurs methodes sous la main grace a toi, je vais pouvoir avancer dans le dév de mon site :wink:

Merci bcp

Je te déconseille de faire ça. Passe plutôt par une table de tri, ou ajoute une colonne à ta table source.

Si tu fais comme ça, tu vas réévaluer la colonne par rapport à ton case pour déterminer l’ordre numérique. Ce qui fait que niveau perf, bof. Tu peux aussi jouer sur le contenu et préfixer par des “000_” tes pays.

Préfixer mes pays?
Le nom de mes pays va apparaitre comme 000_Belgique…? nan?
Pas très sexy
Edité le 27/08/2009 à 20:50

Ben suffit de le gérer à la récupération :slight_smile:

C’est a eviter si possible, il faut changer tout les noms des pays (donc + de boulot qu’un nouvelle colonne), changer ton select pour qu’il utilise un substring et tout tes select future où tu cherchera apres le nom du pays devront se faire en pays like ‘____Pays’ au lieu de pays = ‘Pays’ et ca c pas bien pour les perfs (table scan a tout les coups).

Pour le moment ce que j’ai fais, c’est ajouter un champs en bas de ma table. J’ai mis tinyint comme type, et j’indique des valeurs 1,2,3,… aux éléments devant être triés. Pour le moment ca marche bien :slight_smile:

Yep, c’est l’autre solution. Néanmoins, par rapport à ce que dis oliii, je l’aurais préconisée si tu ne pouvais pas modifier la structure.

Vous imaginez des solutions vraiment compliquées …

Pourquoi ? Tu n’aurais tout simplement pas trié ? :stuck_out_tongue:

(Enfin peut-être que dans ce cas, c’est l’ordre logique, ie: tri alphabétique, qui reste le mieux)

Le tri correspondant généralement à un besoin fonctionnel, je m’y serais évidemment plié. Maintenant, avant de foncer tete baissée sur un ordre de tri sql, j’aurais d’abord envisagé différentes solutions en fonction de :

  • leurs quantités
  • leur évolutivité
  • les contraintes en performance s’ils existent
  • leurs traductions

Et non, il n’existe pas de solutions toutes faites pour tous les besoins … Comme je ne connais pas très bien le besoin, je n’ai pas de solution. CQFD.

Je prends le sujet sur le tard, mais il est vrai que là Vitamin a un peu raison… Le besoin d’afficher des données triées selon un certain ordre (ici en fonction des continents) est une problématique de présentation. La base elle a en charge le stockage et l’assurance de l’intégrité de données. Ajouter une colonne de tri, une table ou le pire les préfixes, c’est descendre au niveau du stockage des données une problématique de présentation. Si demain ce tri ne correspond plus au besoin, on fait quoi ? On intervient sur l’ensemble des données ? N’importe quel DBA qui a un minimum de considération vis à vis de son travail vous envoie à ce moment là un parpaing de 12 à la tête…

Je ne vais pas me risquer à une solution, mais j’aurai penché vers un “select europe union select asie union…”. Pas super performant mais pas du tout intrusif au niveau base. Autre solution plus gourmande en fonction de la quantité de données : suite à un select trié par ordre alphabétique par région, générer autant de listes que de régions et utiliser ces dernières pour le tri…

La solution n’est pas forcément dans une requête SQL de la mort que plus personne ne comprendra dans 2 mois… :wink:

En fait le tri lui même est une donnée qu’il faut souvent conserver, surtout dans un cas comme celui ci ou il peut être assez compliqué ou sans vrai logique. Si l’ordre doit changer et bien on change les données dans la table directement ou avec une petite interface, plus jamais besoin de toucher au requêtes SQL et plus jamais besoin de toucher au programmes/site web.