SQL : Casse-tête d'un tri sur une requête employant UNION ALL

MetalCo
Nouveau WRInaute
Nouveau WRInaute
 
Messages: 34
Inscription: 8 Aoû 2009

SQL : Casse-tête d'un tri sur une requête employant UNION ALL

Message le Mer Fév 03, 2010 23:01

Bonjour à la communauté WRI.
Je me heurte à un souci en matière de tri d'un résultat sql.

Description : Soit 1 table UTILISATEUR composée de 3 champs :
  1. Champ Nom_utilisateur de type texte
  2. Champ Pays_utilisateur de type texte
  3. Champ Partenaire (1 pour partenaire, 0 pour non-partenaire)

J'aimerais projeter une liste des utilisateurs dans l'ordre suivant :
- d'abord les utilisateurs français qui sont partenaires triés par ordre alphabétique
- Puis tous les utilisateurs français (partenaires compris) classés par ordre alphabétique.
[Note : les partenaires seront donc affichés deux fois dans la liste finale].

J'avais pensé à :
(SELECT Nom_utilisateur, Pays_utilisateur
FROM UTILISATEUR
WHERE partenaire="1"
AND pays IN ("France")
ORDER BY Nom_utilisateur ASC)
UNION ALL
(SELECT Nom_utilisateur, Pays_utilisateur
FROM UTILISATEUR
WHERE pays IN ("France")
ORDER BY Nom_utilisateur ASC) ;


Les enregistrements affichés sont les bons et j'ai bien un affichage
1 - des partenaires français
2 - puis utilisateurs français... mais à l'intérieur de ces deux groupes le tri est incohérent.
:arrow: Le Order By visiblement ne passe pas.

Je sollicite quelques techniciens du SQL pour m'aider à y voir plus clair et aboutir à un tri alphabétique à l'intérieur de ces deux groupes...
Merci !


ben64btz
WRInaute discret
WRInaute discret
 
Messages: 204
Inscription: 9 Mai 2006

Re: SQL : Casse-tête d'un tri sur une requête employant UNION ALL

Message le Mer Fév 03, 2010 23:23

Tu as essayé ORDER BY XXX DESC ?

MetalCo
Nouveau WRInaute
Nouveau WRInaute
 
Messages: 34
Inscription: 8 Aoû 2009

Re: SQL : Casse-tête d'un tri sur une requête employant UNION ALL

Message le Mer Fév 03, 2010 23:33

Si il s'agit de tester le tri décroissant sur le champ Nom_utilisateur : oui, j'ai testé, le tri à l'intérieur de ces 2 groupes est tout aussi incohérent. :|

jcaron
WRInaute accro
WRInaute accro
 
Messages: 2687
Inscription: 13 Fév 2004

Re: SQL : Casse-tête d'un tri sur une requête employant UNION ALL

Message le Jeu Fév 04, 2010 2:16

C'est même un hasard que les deux groupes soient l'un après l'autre, UNION ne donne aucune garantie que l'ordre sera conservé, et les clauses ORDER à l'intérieur sont tout bonnement ignorées (sauf s'il y a un LIMIT avec par exemple).

La solution est simple:
SELECT champs FROM (SELECT 1 AS critere,champs FROM table WHERE conditions UNION ALL SELECT 2,champs FROM table WHERE conditions) x ORDER BY critere,autres_criteres_de_tri

Jacques.

jcaron
WRInaute accro
WRInaute accro
 
Messages: 2687
Inscription: 13 Fév 2004

Re: SQL : Casse-tête d'un tri sur une requête employant UNION ALL

Message le Jeu Fév 04, 2010 2:18

NB: je parie une fraise tagada que tout ça est d'ailleurs expliqué dans la doc avec exemples à l'appui. Bref, RTFM :-)

Jacques.

MetalCo
Nouveau WRInaute
Nouveau WRInaute
 
Messages: 34
Inscription: 8 Aoû 2009

Re: SQL : Casse-tête d'un tri sur une requête employant UNION ALL

Message le Jeu Fév 04, 2010 6:38

jcaron a écrit:NB: je parie une fraise tagada que tout ça est d'ailleurs expliqué dans la doc avec exemples à l'appui. Bref, RTFM :-)
Jacques.

Merci Jacques,
tu sais, il ne faut pas m'en vouloir, je code comme une laitue.
jcaron a écrit:La solution est simple:
SELECT champs FROM (SELECT 1 AS critere,champs FROM table WHERE conditions UNION ALL SELECT 2,champs FROM table WHERE conditions) x ORDER BY critere,autres_criteres_de_tri
Jacques.

Si je te suis, j'aboutirais à la requête suivante :
SELECT Nom_utilisateur, Pays_utilisateur
FROM (SELECT 1 AS critere, Nom_utilisateur, Pays_utilisateur
FROM UTILISATEUR
WHERE partenaire="1" AND pays IN ("France")
UNION ALL
SELECT 2, Nom_utilisateur, Pays_utilisateur
FROM UTILISATEUR
WHERE pays IN ("France") )
x ORDER BY critere, Nom_utilisateur ;

Je vais tester. Le x avant Order By, c'est pour moi extra-terrestre, je te donnerai un retour ce soir.
Merci moulte fois, Jacques.
RTFM, c'est une radio de Saint-Domingue, Hein ? :)


Marie-Aude
Modérateur
Modérateur
 
Messages: 11901
Inscription: 5 Juin 2006

Re: SQL : Casse-tête d'un tri sur une requête employant UNION ALL

Message le Jeu Fév 04, 2010 7:19

Tu as oublié as critere après le select 2 et à mon avis tu n'as pas besoin de faire union all il suffit de faire union select
(et puis je ne comprends pas pourquoi tu fais pays IN ("France") et pas pays = "France" ?)

MetalCo
Nouveau WRInaute
Nouveau WRInaute
 
Messages: 34
Inscription: 8 Aoû 2009

Re: SQL : Casse-tête d'un tri sur une requête employant UNION ALL

Message le Jeu Fév 04, 2010 10:06

C'est noté pour As critere.
Je te donnerai la réponse concernant union all et union select... mais à mon avis, union all permet les doublons que union select éliminera.
Pour le critère de restriction IN ("France") : j'ai simplifié volontairement le contexte et la requête qui porte en réalité sur une trentaine de pays.
Merci pour ton intervention, Marie-Aude.

MetalCo
Nouveau WRInaute
Nouveau WRInaute
 
Messages: 34
Inscription: 8 Aoû 2009

Re: SQL : Casse-tête d'un tri sur une requête employant UNION ALL

Message le Jeu Fév 04, 2010 17:14

Merci Jacques et Marie-Aude,
Bilan : Union all n'est pas nécessaire ici, union suffit. Bien vu, Marie-Aude. :)
J'ai compris a quoi servait l'utilité de mettre un alias après une requête imbriquée. Merci Jacques.
Where'sMyFM ? :)

jcaron
WRInaute accro
WRInaute accro
 
Messages: 2687
Inscription: 13 Fév 2004

Re: SQL : Casse-tête d'un tri sur une requête employant UNION ALL

Message le Ven Fév 05, 2010 11:58

Je pense que le "AS critere" dans le deuxième select n'est pas nécessaire: dans un UNION, les noms des champs viennent du premier select, ceux des suivants sont ignorés, il faut juste que le nombre et le type des champs (et leur ordre évidemment) soient les mêmes.

Le "ALL" du UNION n'est pas nécessaire ici parce que le critere (1,2) est différent. Ceci dit, pour la lisibilité je pense que c'est mieux, et pour la performance aussi (un UNION sans ALL oblige le serveur à vérifier s'il y a des doublons, donc ça lui prend plus de temps que de coller tout bêtement à la suite).

Jacques.

PS: le problème n'est pas de coder comme une dinde, c'est juste que tu gagneras beaucoup de temps si tu as le réflexe d'aller lire la doc plutôt que de tourner en rond autour de la question et/ou d'aller poser la question dans un forum. Et en général, en plus de trouver la réponse à ta question, tu vas aussi y apprendre quelques autres trucs au passage, qui serviront bien un jour ou un autre...


Si vous avez aimé cette discussion, partagez-la sur vos réseaux sociaux préférés :

Lectures recommandées sur ce thème :



Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 1 invité