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

Discussion dans 'Développement d'un site Web ou d'une appli mobile' créé par MetalCo, 3 Février 2010.

  1. MetalCo
    MetalCo Nouveau WRInaute
    Inscrit:
    8 Août 2009
    Messages:
    34
    J'aime reçus:
    0
    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é à :
    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 !
     
  2. ben64btz
    ben64btz WRInaute discret
    Inscrit:
    9 Mai 2006
    Messages:
    179
    J'aime reçus:
    0
    Tu as essayé ORDER BY XXX DESC ?
     
  3. MetalCo
    MetalCo Nouveau WRInaute
    Inscrit:
    8 Août 2009
    Messages:
    34
    J'aime reçus:
    0
    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. :|
     
  4. jcaron
    jcaron WRInaute accro
    Inscrit:
    13 Février 2004
    Messages:
    2 646
    J'aime reçus:
    0
    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.
     
  5. jcaron
    jcaron WRInaute accro
    Inscrit:
    13 Février 2004
    Messages:
    2 646
    J'aime reçus:
    0
    NB: je parie une fraise tagada que tout ça est d'ailleurs expliqué dans la doc avec exemples à l'appui. Bref, RTFM :)

    Jacques.
     
  6. MetalCo
    MetalCo Nouveau WRInaute
    Inscrit:
    8 Août 2009
    Messages:
    34
    J'aime reçus:
    0
    Merci Jacques,
    tu sais, il ne faut pas m'en vouloir, je code comme une laitue.
    Si je te suis, j'aboutirais à la requête suivante :
    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 ? :)
     
  7. Marie-Aude
    Marie-Aude WRInaute accro
    Inscrit:
    5 Juin 2006
    Messages:
    16 481
    J'aime reçus:
    2
    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" ?)
     
  8. MetalCo
    MetalCo Nouveau WRInaute
    Inscrit:
    8 Août 2009
    Messages:
    34
    J'aime reçus:
    0
    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.
     
  9. MetalCo
    MetalCo Nouveau WRInaute
    Inscrit:
    8 Août 2009
    Messages:
    34
    J'aime reçus:
    0
    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 ? :)
     
  10. jcaron
    jcaron WRInaute accro
    Inscrit:
    13 Février 2004
    Messages:
    2 646
    J'aime reçus:
    0
    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...
     
  11. clara10
    clara10 WRInaute discret
    Inscrit:
    18 Mai 2011
    Messages:
    75
    J'aime reçus:
    0
    Je déterre un vieux sujet, mais je galère vraiment sur un cas similaire.

    Je comprends pas vraiment pourquoi le résultat donné dans l'exemple marche. Car selon moi le order se fait sur la requête final et mélange du coup les deux sélect, alors que au départ il était question d'afficher d'abord les résultat du premier sélect et ensuite les résultat du deuxième sélect qui eux même étaient déjà trier grasse à un order.

    Voilà mon cas, j'espère que quelqu'un pourra m'aider :

    $query_global = mysql_query("(SELECT SQL_CALC_FOUND_ROWS id FROM matable
    WHERE titre='test' ORDER by ref ASC)
    UNION (SELECT id FROM matable
    WHERE description='test' ORDER by ref ASC)
    LIMIT ".$premierMessageAafficher.", ".$nombreDeMessagesParPage) or die (mysql_error());

    En sachant que je souhaite d'abord faire ressortir les résultat là ou test est dans titre (classé par ref) et ensuite les résultat là ou test est dans description (classé par ref)

    merci de votre aide

    Clara
     
  12. jcaron
    jcaron WRInaute accro
    Inscrit:
    13 Février 2004
    Messages:
    2 646
    J'aime reçus:
    0
    La réponse (avec l'explication du pourquoi et du comment) est dans le 4e message de la discussion.

    Jacques.
     
  13. clara10
    clara10 WRInaute discret
    Inscrit:
    18 Mai 2011
    Messages:
    75
    J'aime reçus:
    0
    Merci de ta réponse. J'ai lu et relu le message et franchement je ne comprends pas. J'ai d'ailleurs testé le code et les résultats ne sont pas affichés d'abord avec le premier sélect et ensuite le deuxième.

    Tous est affiché en même temps.
     
  14. jcaron
    jcaron WRInaute accro
    Inscrit:
    13 Février 2004
    Messages:
    2 646
    J'aime reçus:
    0
    Quel code tu as testé? Parce que le code que tu as donné ne correspond pas du tout à ce qui est expliqué.

    Le principe, c'est que:
    - le ORDER BY dans les différents SELECT qui sont agrégés ne sert à rien, sauf si tu utilises un LIMIT dans le select en question
    - tu ajoutes un champ à chaque SELECT qui correspond à l'ordre de tri des différentes parties (1 pour le premier SELECT, 2 pour le deuxième, etc.)
    - tu mets ton UNION dans une sous-requête
    - tu appliques un ORDER BY sur le SELECT global, en triant en premier par le champ ajouté, puis par les autres champs utiles

    Jacques.
     
Chargement...
Similar Threads - SQL Casse tête Forum Date
Comment rendre une base MySQL case insensitive (non sensible à la casse) ? Développement d'un site Web ou d'une appli mobile 10 Juillet 2010
cache mysql maison Développement d'un site Web ou d'une appli mobile 18 Février 2019
Stocker dans des variables php les fonctions MySql Développement d'un site Web ou d'une appli mobile 2 Février 2019
Prestashop - Comportement bizarre d'une requête SQL e-commerce 1 Décembre 2018
Optimisation d'un champ sql Développement d'un site Web ou d'une appli mobile 17 Novembre 2018
message : [LEGACY][libmysqlclient] Please consider moving to stable and mysqlnd in Administration d'un site Web 8 Novembre 2018
Connexion à un serveur mysql distant Développement d'un site Web ou d'une appli mobile 21 Octobre 2018
Mysql, modifier des chaines avec différents caractères Administration d'un site Web 13 Septembre 2018
Fusionner deux champs sur la même table et même base de donnée Mysql Administration d'un site Web 12 Septembre 2018
Limiter un nombre à une valeur max dans SQL Administration d'un site Web 29 Mars 2018
  1. Ce site utilise des cookies. En continuant à utiliser ce site, vous acceptez l'utilisation des cookies.
    Rejeter la notice