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

Requêtes MySQL Discussion :

Requête Mysql insoluble


Sujet :

Requêtes MySQL

  1. #1
    Membre habitué
    Inscrit en
    Septembre 2007
    Messages
    169
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 169
    Points : 149
    Points
    149
    Par défaut Requête Mysql insoluble
    Bonjour,
    je suis actuellement sur une requête que je n'arrive pas à résoudre. Mon problème est que je voudrais tout faire en une seule requête mais je commence à douter que cela soit possible. En gros j'ai une table d'objet, et à coté 2 autres tables qui référencent ces objets(elles possèdent donc des clés étrangères vers la 1ere table).
    Je voudrais compter pour chaque objet de la 1ere table, combien d'occurence j'en ai dans chacunes des 2 autres tables.
    Voila ce que j'ai actuellement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT `NAME`, count(T2.ID) as NB_T2, count(T3.ID) as NB_T3 
    FROM `T1` 
    LEFT OUTER JOIN T2 ON T2.ID = T1.ID 
    LEFT OUTER JOIN T3 ON T3.ID = T1.ID 
    GROUP BY T1.ID 
    ORDER BY T1.NAME
    Le problème avec cette requete c'est qu'il fait d'abord la jointure avec T2, et ensuite il fait la jointure de tous les résultat de T2 avec T3.
    Donc count(T2.ID) et count(T3.ID) est finalement égal au nombre réel de ligne de T2 multiplié par le nb de ligne de T3.
    Voila, si quelqu'un sait comment corriger cette requete, je suis preneur
    Cartes Pokémon, Yugioh, Magic ?
    Communauté d'échange

  2. #2
    Membre expérimenté
    Avatar de Adjanakis
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    739
    Détails du profil
    Informations personnelles :
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations forums :
    Inscription : Avril 2004
    Messages : 739
    Points : 1 351
    Points
    1 351
    Par défaut
    Bonjour,

    Je crois qu'il faudrait utiliser une UNION, mais pour en être sûr, pourrais-tu donner un exemple de résultat voulu ?
    Pensez au tag

  3. #3
    Membre confirmé
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Mars 2006
    Messages
    400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Mars 2006
    Messages : 400
    Points : 562
    Points
    562
    Par défaut
    Pour résoudre un problème apparamment complexe, il convient le plus souvent de le diviser en problèmes plus simples.

    Dans ton cas, il convient d'abord de compter le nombre d'occurence d'une valeur dans chaque table (1.), puis de regouper les résultats au sein d'une requête unique (2.).

    1. Compter le nombre d'occurences

    Pour la table T2 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT T2.ID, count(*) AS NB_T2
    FROM T2
    GROUP BY T2.ID
    Pour la table T3 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT T3.ID, count(*) AS NB_T3
    FROM T3
    GROUP BY T3.ID
    Ces requêtes vont retourner le nombre de fois où chaque ID apparait dans chacune des tables T2 et T3.
    L'ID est sélectionné pour ensuite effectuer la jointure (2.).

    2. Regrouper les résultats

    Une méthode simple de regouper les résultats de plusieurs requêtes, c'est d'utiliser des sous-requêtes.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT T1.NAME, R2.NB_T2, R3.NB_T3
    FROM T1
    LEFT JOIN (SELECT T2.ID, count(*) AS NB_T2 FROM T2 GROUP BY T2.ID) AS R2 ON T1.ID=R2.ID
    LEFT JOIN (SELECT T3.ID, count(*) AS NB_T3 FROM T3 GROUP BY T3.ID) AS R3 ON T1.ID=R3.ID
    GROUP BY T1.ID
    En incluant une sous-requête dans la clause FROM, on peut utiliser les résultats d'une requête, comme s'il s'agissait de tables (R2 et R3).
    Ces "tables" sont constituées de 2 champs. L'un contient un ID, et l'autre le nombre de fois où cet ID apparait dans la table T2 ou T3.

    Ensuite, il ne reste plus qu'à joindre ces 2 "tables" à la table principale, à l'aide de jointures.

  4. #4
    Membre habitué
    Inscrit en
    Septembre 2007
    Messages
    169
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 169
    Points : 149
    Points
    149
    Par défaut
    Effectivement je viens de tester, ca a l'air de faire ce que je voulais jeremya. Par contre au niveau des performances ca m'a l'air horrible, tu fais les 2 selects sur les 2 tables en entier, pour finalement n'en récupérer qu'une partie.
    Je pense que cela est inévitable.

    Si oui, T2 et T3 contiennent finalement les memes champs, est ce qu'il vaudrait mieux que je les fusionnent avec un champ supplémentaire indiquant leur provenance ?

    Merci beaucoup en tout cas
    Cartes Pokémon, Yugioh, Magic ?
    Communauté d'échange

  5. #5
    Membre expérimenté
    Avatar de Adjanakis
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    739
    Détails du profil
    Informations personnelles :
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations forums :
    Inscription : Avril 2004
    Messages : 739
    Points : 1 351
    Points
    1 351
    Par défaut
    Oui c'est tout à fait possible, c'est d'ailleurs pour cela que je parlais d'union. Plutôt que d'expliquer maladroitement pourquoi cette solution est meilleure, je laisse la parole à sqlpro:Cosmétique...
    Pensez au tag

  6. #6
    Membre habitué
    Inscrit en
    Septembre 2007
    Messages
    169
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 169
    Points : 149
    Points
    149
    Par défaut
    Désolé du temps de réponse, mais j'avais d'autres trucs en parallèle.
    J'ai finalement décidé de fusionner les 2 tables, je pense que niveau performance cette méthode est meilleure que les 2 jointures proposées(qui marchent parfaitement aussi). Reprenez moi si je me trompe.

    Voila la version actuelle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT T1.NAME, SUM(CASE WHEN T2.TYPE = 'type1' THEN 1 ELSE 0) AS NB_T2, SUM(CASE WHEN T2.TYPE = 'type2' THEN 1 ELSE 0) AS NB_T3 FROM T1
    NATURAL LEFT JOIN T2
    GROUP BY T1.ID
    Cartes Pokémon, Yugioh, Magic ?
    Communauté d'échange

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

Discussions similaires

  1. Requète MySQL >> Postgresql
    Par genova dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 19/08/2005, 09h05
  2. Requête MYSQL LIKE particulière
    Par TheDarkLewis dans le forum Requêtes
    Réponses: 9
    Dernier message: 05/12/2004, 15h50
  3. Arrêt de l'exécution d'une requête MySQL dans DELPHI.
    Par joelmarc dans le forum Bases de données
    Réponses: 9
    Dernier message: 11/10/2004, 16h11
  4. surcharge de requête MySQL
    Par simoryl dans le forum Requêtes
    Réponses: 4
    Dernier message: 15/06/2004, 10h43
  5. requête mysql sous php
    Par remi59 dans le forum Débuter
    Réponses: 9
    Dernier message: 03/07/2003, 10h39

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