IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage SQL Discussion :

ordonner le résultat d'une requête selon une autre requête


Sujet :

Langage SQL

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 136
    Points : 112
    Points
    112
    Par défaut ordonner le résultat d'une requête selon une autre requête
    Bonjour,

    je suis en train de faire une requête qui peut paraitre simple mais est une vraie usine à gaz... Pour simplifier, disons que j'ai 3 tables. Des logiciels peuvent être installés à bord de véhicules, et chaque véhicule a une version donnée d'un logiciel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    VEHICULE  1 <------> 0..* VERSION 0..* <--------> 1 LOGICIEL
       id                         id                   id
      numero                    numero                 nom
    J'affiche le tableau suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    numeroVehicule | nomLogiciel1 | nomLogiciel2
         50001     |      2.0     |      5.4
         50002     |      2.1     |      5.5
         50003     |      2.0     |      5.1
    Mon problème se pose lorsque je veux trier mes résultats selon la version pour un nom de logiciel donné. Dans l'idéal, si ça existait, il me faudrait quelque chose du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT *
    FROM vehicule
    ORDER BY (SELECT numero
              FROM version, logiciel
              WHERE version.idLogiciel= logiciel.id
              AND logiciel.nom="nomLogiciel2")
    Je pourrais faire un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT *
    FROM vehicule
    WHERE id IN
             (SELECT id
              FROM vehicule
              WHERE nom_logiciel="nomLogiciel2"
              ORDER BY nom_logiciel)
    mais je ne pense pas que l'ordre de la requête imbriquée soit conservé pour la requête principale.... (d'autant plus que la requête est en fait un peu plus compliquée que ça et que j'aurai d'autres requêtes imbriquées....).

    Quelqu'un voit-il un moyen pour "recopier" le tri d'une requête dans une autre requête ayant le même type de résultat? ou une autre solution pour remédier à mon problème??

    Merci

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    Pouvez-vous nous fournir votre requête complète ?

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    861
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 861
    Points : 965
    Points
    965
    Par défaut
    Bonjour,
    Citation Envoyé par brassouille Voir le message
    J'affiche le tableau suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    numeroVehicule | nomLogiciel1 | nomLogiciel2
         50001     |      2.0     |      5.4
         50002     |      2.1     |      5.5
         50003     |      2.0     |      5.1
    Mon problème se pose lorsque je veux trier mes résultats selon la version pour un nom de logiciel donné.
    Je ne comprends pas bien votre problème, vous affichez ce tableau, on doit en déduire que vous avez fait une requête qui retourne des résultats tels quels, ou c'est coté appli que vous gérez l'affichage?
    Si vous avez fait la requête, un simple order by NomLogiciel devrait suffire non?
    Si les données sont mises en forme au niveau de votre appli, le tri devrait aussi se faire à ce niveau.

    Peut être que la requête dont découle votre tableau pourrait aussi nous être utile, et pourquoi pas le nom et la version de votre SGBD.

    EDIT : je ferai bien de rafraichir ma page avant de poster des fois

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 136
    Points : 112
    Points
    112
    Par défaut
    Bonjour,
    merci pour vos réponses.

    @Waldar Je n'ai pas encore la requête complète, j'ai juste fait un tableau avec des valeurs bidons pour vous exposer le problème. Elle sera en fait plus compliquée pour plusieurs raisons :
    - certains logiciels peuvent ne pas être présents à bord des véhicules, il faut que j'affiche quand même ces véhicules (je pense être obligé de faire une UNION entre les véhicules triés par le nom du logiciel, et ceux qui n'ont pas ce logiciel installé)
    - l'utilisateur peut choisir une option "uniquement les véhicules non à jour", ce qui signifie que je ne récupèrerai que les véhicules dont au moins une version de logiciel est différente d'une version de référence fixe. Je pense le faire par une requête imbriquée du genre "where vehicule.id in (...select vehicules non à jour...)"
    - je fais un LIMIT pour n'afficher que les 10 premiers résultats
    - et pour couronner le tout c'est du HQL

    @Snipah
    Oui mon tableau est affiché coté appli, mais je préfère faire le tri avant car la table est très grosse et je ne récupère les résultats que par 10 à la fois en utilisant LIMIT et OFFSET. Si je fais mon tri coté appli, je serai obligé de récupérer la totalité des éléments pour pouvoir ensuite les trier...
    Je ne cherche par à faire un ORDER BY nomLogiciel, mais un ORDER BY version **pour un nom de logiciel donné**, c'est tout le problème...
    J'utilise MySQL 5.1.35, le tout via java/hibernate en HQL.
    Je n'avais pas précisé tout ça pour ne pas compliquer les choses car je pense qu'il s'agit d'un simple problème de syntaxe SQL

    Enfin ça devient de plus en plus embrouillé dans ma tête là, j'espère que j'aurai les idées un peu plus claires demain

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 136
    Points : 112
    Points
    112
    Par défaut
    En fait pour être plus clair, le retour non formaté que j'aurais de SQL serait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    numeroVehicule - logiciel.nom - version.numero
    50001 - nomLogiciel1 - 2.0
    50001 - nomLogiciel2 - 5.4
    50002 - nomLogiciel1 - 2.1
    50002 - nomLogiciel2 - 5.5
    50003 - nomLogiciel1 - 2.0
    50003 - nomLogiciel2 - 5.1

    que je dois trier selon version.numero POUR LE NOM DE LOGICIEL nomLogiciel2

  6. #6
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    Ok on va partir là-dessus, votre requête donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    numeroVehicule - logiciel.nom - version.numero
    50001 - nomLogiciel1 - 2.0
    50001 - nomLogiciel2 - 5.4
    50002 - nomLogiciel1 - 2.1
    50002 - nomLogiciel2 - 5.5
    50003 - nomLogiciel1 - 2.0
    50003 - nomLogiciel2 - 5.1
    Si votre paramètre est nomLogiciel2, vous voullez obtenir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    numeroVehicule - logiciel.nom - version.numero
    50002 - nomLogiciel2 - 5.5
    50001 - nomLogiciel2 - 5.4
    50003 - nomLogiciel2 - 5.1
    50001 - nomLogiciel1 - 2.0
    50002 - nomLogiciel1 - 2.1
    50003 - nomLogiciel1 - 2.0
    Comment trier les trois derniers ?

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 136
    Points : 112
    Points
    112
    Par défaut
    Bonjour,
    l'ordre des lignes suivantes n'a pas d'importance, hibernate prendra en compte seulement la première occurence de chacun des véhicules rencontrés pour ordonner la liste d'objets qu'il génèrera.
    Il faut donc simplement arriver à ordonner les trois premières lignes.

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    135
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 135
    Points : 164
    Points
    164
    Par défaut
    je n'ai pas saisi ton traitement,mais est ce que le where ci-dessous n'est pas suffisant?

    l'ordre des lignes suivantes n'a pas d'importance, hibernate prendra en compte seulement la première occurence de chacun des véhicules rencontrés pour ordonner la liste d'objets qu'il génèrera.
    Il faut donc simplement arriver à ordonner les trois premières lignes.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Where nom='nomLogiciel2'

  9. #9
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    Si la réponse du dessus ne convient pas, vous pouvez faire le tri suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ORDER BY
        CASE nom_logiciel WHEN 'nomLogiciel2' THEN 0 ELSE 1 END ASC,
        version DESC

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 136
    Points : 112
    Points
    112
    Par défaut
    @teach
    Non ça ne suffit pas : même si l'ordre des trois dernières lignes n'est pas important, j'ai besoin qu'elles soient présentes. En mettant un where elles ne seront pas retournées...

    @Waldar
    Ca m'a l'air parfait, je n'y aurais jamais pensé, merci
    C'est du SQL de base ou c'est spécifique à un SGBD?

  11. #11
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    Case oui c'est dans la norme SQL, ça devrait fonctionner à peu près partout.

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 136
    Points : 112
    Points
    112
    Par défaut
    ok merci beaucoup

  13. #13
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 136
    Points : 112
    Points
    112
    Par défaut
    j'avais un peu peur que la syntaxe ne passe pas en HQL, et que je sois obligé d'écrire la requête SQL directement à la main, mais ça marche parfaitement en HQL
    Et je ne suis même pas obligé de faire une union sur les véhicules qui ne possèdent pas ce logiciel (c'est à dire dont version = null pour ce logiciel) comme je craignais devoir le faire en faisant une requête imbriquée...

    le résultat est EXACTEMENT ce que je cherchais, merci merci merci

    (il faut juste remplacer le version DESC par version.numero DESC, sinon ça me trie sur les id de version au lieu de leur numero )

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 136
    Points : 112
    Points
    112
    Par défaut
    Re-bonjour,

    mon tableau doit pouvoir être trié dans les deux sens. J'ai donc repris la requête pour faire le tri par ordre croissant. Je continue à placer les logiciels de nom "nomLogiciel2" en haut de mon tableau et les trie ensuite par ordre croissant de version (je conserve le premier ASC, et change le DESC en ASC):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ORDER BY
        CASE nom_logiciel WHEN 'nomLogiciel2' THEN 0 ELSE 1 END ASC,
        version.numero ASC
    Ca marche bien à une exception près : les valeurs nulles. Dans le tri par ordre décroissant, elles apparaissent à la fin. Dans le tri par ordre croissant, je voudrais donc qu'elles apparaissent en premier. Je pensais donc faire un :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ORDER BY
        CASE nom_logiciel WHEN null THEN 0 WHEN 'nomLogiciel2' THEN 1 ELSE 2 END ASC,
        version.numero ASC
    mais ça ne marche pas.... même quand nom_logiciel vaut null, on passe dans le else et la valeur retenue est 2.

    Bizarrement, ça marche en faisant comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ORDER BY
        CASE WHEN nom_logiciel IS null THEN 0 ELSE 1 END,
        CASE nom_logiciel WHEN null THEN 0 WHEN 'nomLogiciel2' THEN 1 ELSE 2 END ASC,
        version.numero ASC
    Voyez-vous une raison pour laquelle le "when null" ne fonctionne pas alors que le "is null" fonctionne?
    Ai-je un moyen de "factoriser" mon code ou dois-je conserver les deux case?

  15. #15
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 106
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 106
    Points : 28 393
    Points
    28 393
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CASE expTest 
     WHEN NULL THEN res0
     WHEN exp1 THEN res1
     WHEN exp2 THEN res2
     ELSE resElse
    END
    est équivalent à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CASE 
      WHEN expTest = NULL THEN res1
      WHEN expTest = exp1 THEN res1
       WHEN expTest = exp2 THEN res2
     ELSE resElse
    END
    Sans commentaire

  16. #16
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    Oui, pour gérer les nulls il faut l'écrire différemment :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    ORDER BY
        CASE
          WHEN nom_logiciel IS NULL          THEN 0 
          WHEN nom_logiciel = 'nomLogiciel2' THEN 1
          ELSE 2
        END ASC,
        version.numero ASC

  17. #17
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 136
    Points : 112
    Points
    112
    Par défaut
    @al1_24
    et si je me souviens bien, "expTest = NULL" ou même "null=null" retourne toujours false en SQL, c'est ça?

    @Waldar
    merci pour la syntaxe

  18. #18
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 106
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 106
    Points : 28 393
    Points
    28 393
    Par défaut
    Citation Envoyé par brassouille Voir le message
    et si je me souviens bien, "expTest = NULL" ou même "null=null" retourne toujours false en SQL, c'est ça?
    (exp = NULL) ne retourne ni TRUE, ni FALSE, ni NULL mais UNKNOWN...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XL-2003] Recopier une ligne selon une valeur d'une cellule donnée.
    Par bokgkik dans le forum Excel
    Réponses: 2
    Dernier message: 07/12/2011, 19h00
  2. Réponses: 1
    Dernier message: 21/01/2011, 10h17
  3. [XL-2007] Afficher une checkbox dans une feuille si une checkbox d'une autre feuille est cochée
    Par JessieCoutas dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 18/08/2009, 13h35
  4. Réponses: 12
    Dernier message: 12/09/2007, 16h28
  5. Recherche une valeur d'une cellule dans une colonne d'une autre feuille
    Par kourria dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 21/06/2007, 13h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo