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 :

Jointure par la gauche


Sujet :

Langage SQL

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2008
    Messages : 71
    Points : 48
    Points
    48
    Par défaut Jointure par la gauche
    Bonjour,

    Je vous explique le schéma de ma BD (je n'ai fait que la reprendre, je ne l'ai pas créée ):

    table -dateconv qui contient un id et les dates associées
    - inscription
    - orientation
    - nomoption
    - nonsection
    - categorie_ens

    Je veux savoir jour/jour combien d'inscriptions il y a eu dans une catégorie donnée, et ce même si il n'y a pas eu d'inscriptions un jour -> par exemple le 27/06 : 0 inscriptions.

    Voici ma requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    SELECT dateconv.valdate
     , COUNT(IF(categorie_ens.cateid IS NOT NULL,ins_rt_etu,NULL)) 
    FROM dateconv 
     LEFT JOIN inscription 
      ON inscription.insdate=dateconv.id_date 
     LEFT JOIN orientation 
      ON orientation.oriid = inscription.ins_rt_ori 
     LEFT JOIN nomoption
      ON nomoption.nopid=orientation.ori_rt_nop 
     LEFT JOIN nomsection
      ON nomsection.nscid = nomoption.nop_rt_nsc
     LEFT JOIN categorie_ens
      ON categorie_ens.cateid = nomsection.nsc_rt_cate
      AND categorie_ens.catenom="Technique" 
    WHERE dateconv.id_date>=39985 
     AND dateconv.id_date<=39992  
    GROUP BY (dateconv.id_date)
    Si je retire le count et le group by, il m'affiche toutes les inscriptions qui se sont déroulées entre les dates sélectionnées, et remplace la catégorie par NULL si ce n'est pas "Technique".

    Y a-t-il une possibilité pour ne pas afficher du tout les lignes où la catégorie est NULL?

    Le but est de pouvoir alléger le traitement pour le COUNT car j'ai 170 dates à afficher, et lorsque j'en affiche 60, celà prend déjà plus de 30 secondes...

    Merci

  2. #2
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 950
    Points : 5 849
    Points
    5 849
    Par défaut
    Y a-t-il une possibilité pour ne pas afficher du tout les lignes où la catégorie est NULL?
    Il suffit de filtrer dans le WHERE sur "technique" et non dans la condition de jointure (le ON)

    Sinon concernant les perfs, je ne pense pas que tu ais besoin de tous ces LEFT JOIN, à mon avis seul le 1er est vraiment nécessaire fonctionnelement.
    Qu'est ce que ça donne avec des INNER JOIN dans une sous requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    SELECT dateconv.valdate
     , COUNT(*) 
    FROM dateconv 
     LEFT JOIN
    	(select inscription.insdate
    	 FROM inscription 
    	 JOIN orientation ON orientation.oriid = inscription.ins_rt_ori 
     	 JOIN nomoption ON nomoption.nopid=orientation.ori_rt_nop 
     	 JOIN nomsection ON nomsection.nscid = nomoption.nop_rt_nsc
     	 JOIN categorie_ens ON categorie_ens.cateid = nomsection.nsc_rt_cate
    	 WHERE categorie_ens.catenom="Technique" 
    	) as t
      ON dateconv.id_date = t.insdate
    WHERE dateconv.id_date>=39985 
     AND dateconv.id_date<=39992  
    GROUP BY dateconv.id_date
    Sinon ta base est elle correctement indexée ?
    Tu peux également regarder le plan d'exécution de la requête avec EXPLAIN

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2008
    Messages : 71
    Points : 48
    Points
    48
    Par défaut
    Super,

    Ce qu'il me fallait exactement était :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    SELECT dateconv.valdate
     , COUNT(t.ins_rt_etu) 
    FROM dateconv 
     LEFT JOIN
    	(SELECT inscription.insdate, inscription.ins_rt_etu
    	 FROM inscription 
    	 JOIN orientation ON orientation.oriid = inscription.ins_rt_ori 
     	 JOIN nomoption ON nomoption.nopid=orientation.ori_rt_nop 
     	 JOIN nomsection ON nomsection.nscid = nomoption.nop_rt_nsc
     	 JOIN categorie_ens ON categorie_ens.cateid = nomsection.nsc_rt_cate
    	 WHERE categorie_ens.catenom="Technique" 
    	) AS t
      ON dateconv.id_date = t.insdate
    WHERE dateconv.id_date>=39985 
     AND dateconv.id_date<=40194 
    GROUP BY dateconv.id_date
    Un grand merci

  4. #4
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 950
    Points : 5 849
    Points
    5 849
    Par défaut
    oui c'est le count(*), désolé, que donne cette requête:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    SELECT dateconv.valdate
     , COUNT(t.insdate) 
    FROM dateconv 
     LEFT JOIN
    	(select inscription.insdate
    	 FROM inscription 
    	 JOIN orientation ON orientation.oriid = inscription.ins_rt_ori 
     	 JOIN nomoption ON nomoption.nopid=orientation.ori_rt_nop 
     	 JOIN nomsection ON nomsection.nscid = nomoption.nop_rt_nsc
     	 JOIN categorie_ens ON categorie_ens.cateid = nomsection.nsc_rt_cate
    	 WHERE categorie_ens.catenom="Technique" 
    	) as t
      ON dateconv.id_date = t.insdate
    WHERE dateconv.id_date>=39985 
     AND dateconv.id_date<=39992  
    GROUP BY dateconv.id_date
    Et sinon niveau perf c'est mieux ?

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2008
    Messages : 71
    Points : 48
    Points
    48
    Par défaut
    Les performances ne sont même pas comparables, j'ai la réponse en 1seconde et quelque chose pour l'année complète, donc en mettant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    WHERE dateconv.id_date>=39985 
     AND dateconv.id_date<=40194

  6. #6
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 950
    Points : 5 849
    Points
    5 849
    Par défaut
    cool... bonne fin de journée

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 22/12/2008, 16h25
  2. [Hibernate 3.2.5] Jointure par Criteria
    Par pbossard dans le forum Hibernate
    Réponses: 2
    Dernier message: 06/11/2007, 10h15
  3. Acceder a une webaprt par menu gauche
    Par barnet dans le forum SharePoint
    Réponses: 2
    Dernier message: 23/10/2007, 11h11
  4. Syntaxe des jointures a droite/gauche dans le WHERE
    Par gregb34 dans le forum Langage SQL
    Réponses: 4
    Dernier message: 23/01/2007, 11h28
  5. recherche de jointure par requête
    Par vacknov dans le forum Requêtes
    Réponses: 4
    Dernier message: 25/07/2006, 22h21

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