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 LEFT JOIN avec Double COUNT


Sujet :

Langage SQL

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2002
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2002
    Messages : 145
    Points : 59
    Points
    59
    Par défaut Jointure LEFT JOIN avec Double COUNT
    Bonjour,

    Je n'arrive pas à m'en sortir avec une requête, là voici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT c.nom as 'contrat', COUNT(a.id) as 'recus', COUNT(e.id) as 'nb_enquete', COUNT(e.id) as 'nb_sms'
    FROM contrat c
    	    LEFT JOIN appels a ON c.id = a.id_contrat AND DATE(a.date) >= '2015-02-01' AND DATE(a.date) <= '2015-02-28'
    	    LEFT JOIN enquete e ON c.id = e.id_contrat AND DATE(e.date) >= '2015-02-01' AND DATE(e.date) <= '2015-02-28'
                LEFT JOIN gqm_sms gs ON c.id = gs.id_contrat AND gs.statut = 1 AND gs.note != 0 AND DATE(gs.date) >= '2015-02-01' AND DATE(gs.date) <= '2015-02-28'
    GROUP BY c.id
    En gros l'idée est d'avoir le nombre d’enquête et d'appel par contrat sur le mois dernier pour avoir quelques chose comme ça

    CONTRAT 1 | 105 | 2 | 9
    CONTRAT 2 | 85 | 15 | 12
    CONTRAT 3 | 85 | 3 | 20

    Mais ma requête affiche

    CONTRAT 1 | 800 | 800 | 800
    CONTRAT 2 | 500 | 500 | 500
    CONTRAT 3 | 300 | 300 | 300

    Vous auriez une idée ?

    Pour info, si je rajoute 3 DISTINCT ça fonctionne mais la requête est interminable, voir crash (beaucoup de données) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT c.nom as 'contrat', COUNT(DISTINCT a.id) as 'recus', COUNT(DISTINCT  e.id) as 'nb_enquete', COUNT(DISTINCT e.id) as 'nb_sms'
    FROM contrat c
    	    LEFT JOIN appels a ON c.id = a.id_contrat AND DATE(a.date) >= '2015-02-01' AND DATE(a.date) <= '2015-02-28'
    	    LEFT JOIN enquete e ON c.id = e.id_contrat AND DATE(e.date) >= '2015-02-01' AND DATE(e.date) <= '2015-02-28'
                LEFT JOIN gqm_sms gs ON c.id = gs.id_contrat AND gs.statut = 1 AND gs.note != 0 AND DATE(gs.date) >= '2015-02-01' AND DATE(gs.date) <= '2015-02-28'
    GROUP BY c.id
    Les 3 jointures essayée une à une sont pourtant très rapide et ne posent aucun problème (il y'a également des index) ... mais ensemble ça ne passe pas, elles semblent se démultiplier entre elles

  2. #2
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Bonjour,

    Effectivement, votre requête produit un pseudo produit cartésien entre vos trois tables appels, enquete et gqm_sms.

    Vous pouvez essayer de faire le regroupement en amont, et de joindre le résultat de ces regroupements :

    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    SELECT 
    		c.nom as 'contrat'
    	,	recus
    	,	nb_enquete
    	,	nb_sms
    FROM contrat c
    LEFT JOIN (
    		SELECT id_contrat, COUNT(*) as 'recus'
    		FROM appels 
    		WHERE DATE(date) >= '2015-02-01' AND DATE(date) <= '2015-02-28'
    		GROUP BY id_contrat
    	)a 
    		ON c.id = a.id_contrat 
    LEFT JOIN (
    		SELECT id_contrat, COUNT(*) as 'nb_enquete'
    		FROM enquete 
    		WHERE DATE(date) >= '2015-02-01' AND DATE(date) <= '2015-02-28'
    		GROUP BY id_contrat
    	)e 
    		ON c.id = e.id_contrat 
    LEFT JOIN (
    		SELECT id_contrat, COUNT(*) as 'nb_sms'
    		FROM gqm_sms  
    		WHERE DATE(date) >= '2015-02-01' AND DATE(date) <= '2015-02-28'
    		AND statut = 1 AND note != 0
    		GROUP BY id_contrat
    	)gs 
    		ON c.id = gs.id_contrat

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2002
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2002
    Messages : 145
    Points : 59
    Points
    59
    Par défaut
    Super ça fonctionne merci !

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

Discussions similaires

  1. [AC-2007] Recherche équivalent Left Join avec jointure =
    Par neupont dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 24/10/2012, 18h58
  2. Left join avec 3 tables
    Par MathiasMathias dans le forum Langage SQL
    Réponses: 1
    Dernier message: 10/04/2007, 00h45
  3. Réponses: 6
    Dernier message: 23/01/2007, 10h17
  4. LEFT JOIN avec Oracle 8i ne va pas... doit utiliser (+)
    Par loikiloik dans le forum Langage SQL
    Réponses: 10
    Dernier message: 21/04/2004, 16h38

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