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

Développement SQL Server Discussion :

Count dans plusieurs tables


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Lycéen
    Inscrit en
    Mars 2013
    Messages
    65
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Mars 2013
    Messages : 65
    Par défaut Count dans plusieurs tables
    Bonjour à tous et toutes!

    J'ai une base de données (SQL MANAGER) avec plusieurs tables "principale" (contacts, société, etc...) dans laquelle chaque entrée peut-être reliée à x autres, du coup des tables de relations existent entre chacune d'entre elle (contact-contact, contact-société, contacts-..., ...).

    Je voudrais une requête qui me permet de voir à combien d'autre enregistrement de chaque type est relié chaque contact. Voilà la requête que j'ai faite :
    Code SQL : 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
    SELECT Cont.NAME AS Nom
          ,Cont.FIRSTNAME AS Prenom
          ,Count(ContCont.K_CONTACT) AS Contacts
          ,Count(ContDocu.K_CONTACT) AS Documents
          ,Count(ContActi.K_CONTACT) AS Actions
          ,Count(ContPubl.K_CONTACT) AS Publications
          ,Count(ContOppo.K_CONTACT) AS Opportunities
          ,Count(ContMail.K_CONTACT) AS Mails
          ,Count(ContProd.K_CONTACT) AS Products
          ,Count(ContProj.K_CONTACT) AS Projects
          ,Count(ContProf.K_CONTACT) AS Profiles
          ,Count(ContTmpl.K_CONTACT) AS Templates
            FROM CONTACTS Cont
            LEFT JOIN CONT_COMP ContComp ON ContComp.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN COMPANIES Comp ON ContComp.K_COMPANY=Comp.K_COMPANY
            LEFT JOIN CONT_CONT ContCont ON ContCont.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN DOCU_CONT ContDocu ON ContDocu.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN ACTI_CONT ContActi ON ContActi.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN PUBL_CONT ContPubl ON ContPubl.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN OPPO_CONT ContOppo ON ContOppo.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN MAIL_CONT ContMail ON ContMail.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN PROD_CONT ContProd ON ContProd.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN PROJ_CONT ContProj ON ContProj.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN PROF_CONT ContProf ON ContProf.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN TMPL_CONT ContTmpl ON ContTmpl.K_CONTACT=Cont.K_CONTACT
              WHERE Comp.KIND=12
              GROUP BY Cont.NAME, Cont.FIRSTNAME
              ORDER BY Cont.NAME, Cont.FIRSTNAME


    Dès que plusieurs Count à une valeur supérieur à 0 un produit cartésien est fait entre ceux-ci...
    Par exemple ci-dessous, la 2ème ligne est correcte, mais pas la 1ère: les 0 sont corrects mais normalement: Actions=6, Publications=13 et Profiles=5 (6X13X5=390)
    Nom : SQLTriage.PNG
Affichages : 373
Taille : 5,4 Ko
    Quelqu'un peut-il m'aider svp ? Plus tard j'exporterais ces données dans un fichier Excel

    Merci à d'avance!^^

    PS: la structure de la base de données n'est pas modifiable, elle vient d'un crm.

    J'ai également essayé avec cette requête, j'ai exactement le même résultat
    Code SQL : 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 Cont.NAME AS Nom
          ,Cont.FIRSTNAME AS Prenom
          ,Count(ContComp.K_CONTACT) AS Companies
          ,Count(ContCont.K_CONTACT2) AS Contacts
          ,Count(ContDocu.K_DOCUMENT) AS Documents
          ,Count(ContActi.K_ACTION) AS Actions
          ,Count(ContPubl.K_PUBLICATION) AS Publications
          ,Count(ContOppo.K_OPPORTUNITY) AS Opportunities
          ,Count(ContMail.K_MAIL) AS Mails
          ,Count(ContProd.K_PRODUCT) AS Products
          ,Count(ContProj.K_PROJECT) AS Projects
          ,Count(ContProf.K_PROFILE) AS Profiles
          ,Count(ContTmpl.K_TEMPLATE) AS Templates
            FROM Actilan.adminactilan.CONTACTS Cont
            LEFT JOIN CONT_COMP ContComp ON ContComp.K_CONTACT=Cont.K_CONTACT
    	LEFT JOIN COMPANIES Comp ON ContComp.K_COMPANY=Comp.K_COMPANY
            LEFT JOIN CONT_CONT ContCont ON ContCont.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN DOCU_CONT ContDocu ON ContDocu.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN ACTI_CONT ContActi ON ContActi.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN PUBL_CONT ContPubl ON ContPubl.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN OPPO_CONT ContOppo ON ContOppo.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN MAIL_CONT ContMail ON ContMail.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN PROD_CONT ContProd ON ContProd.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN PROJ_CONT ContProj ON ContProj.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN PROF_CONT ContProf ON ContProf.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN TMPL_CONT ContTmpl ON ContTmpl.K_CONTACT=Cont.K_CONTACT
    	  WHERE Comp.KIND=12
              GROUP BY Cont.NAME, Cont.FIRSTNAME
    	  ORDER BY Cont.NAME, Cont.FIRSTNAME

  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
    Par défaut
    Bonjour,

    Deux solutions :

    1/ vous pouvez ajouter un DISTINCT dans les COUNT de votre deuxième requête (il faut bien faire un distinct sur les clef des tables jointes)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    ...
    ,Count(DISTINCT ContDocu.K_DOCUMENT) AS Documents
    ...
    Soit vous préagregez dans des sous requetes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    SELECT ...
        , DOCU_CONT.Nb AS Documents
    ...
    FROM ...
    LEFT JOIN (
        SELECT K_CONTACT
            , COUNT(*) AS Nb
        FROM DOCU_CONT 
        GROUP BY K_CONTACT
     ) ContDocu ON ContDocu.K_CONTACT=Cont.K_CONTACT
    ...

  3. #3
    Membre confirmé
    Homme Profil pro
    Lycéen
    Inscrit en
    Mars 2013
    Messages
    65
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Mars 2013
    Messages : 65
    Par défaut
    Merci pour votre réponse!

    La 1ere requete (avec les DISTINCT) est vraiment longue à l'execution (25min et aucune ligne n'est sortie sur les 2350 attendues)

    En revanche je suis presque arrivé à faire fonctionner la 2ème : Je n'arrive pas à faire la bonne jointure entre CONTACTS et COMPANIES à cause de la condition sur COMPANIES.KIND
    Le résultat de la query correspond a peu près à l'image ci-dessous. Dans mon cas A est ma table CONTACTS, B ma table COMPANIES et l'intersection est ma table CONT_COMP la requête doit sortir:
    - chaque ligne de A (chaque CONTACTS) qui ne sont pas dans l'intersection (donc CONT_COMP.K_COMPANY IS NULL), donc la colonne ContComp.Nb=0 ou null
    ET
    - chaque ligne de A (chaque CONTACTS) qui sont présents dans l'intersection où COMPANIES.KIND=12 : ces lignes doivent avoir la colonne ContComp.Nb égale ou nombre de lien
    Nom : sql-left-join-300.png
Affichages : 233
Taille : 15,9 Ko

    J'ai 1 requête qui fonctionne presque:

    Pour la 1ère : le chiffre dans les colonnes sont bons, problème c'est qu'elles me sort TOUS les CONTACTS. En gros faut filtrer les COMPANIES.KIND!=12.
    J'ai essayé de mettre cette condition entre la ligne 19 et 20 (dans un WHERE) ça ne marche pas,
    J'ai aussi essayé dans le ON ligne 19, ça ne marche pas non plus
    INNER JOIN COMPANIES Comp ON (CONT_COMP.K_COMPANY=Comp.K_COMPANY AND Comp.KIND=12)
    Et enfin j'ai esayé de faire comme dans mon exemple, ça ne marche pas non plus..

    Code SQL : 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
    30
    31
    32
    /* SURPLUS Comp.KIND!=12 */
    SELECT Cont.NAME AS Nom
          ,Cont.FIRSTNAME AS Prenom
        ,ContComp.Nb AS Companies
          ,ContCont.Nb AS Contacts
          ,ContDocu.Nb AS Documents
          ,ContActi.Nb AS Actions
          ,ContPubl.Nb AS Publications
          ,ContOppo.Nb AS Opportunities
          ,ContMail.Nb AS Mails
          ,ContProd.Nb AS Products
          ,ContProj.Nb AS Projects
          ,ContProf.Nb AS Profiles
          ,ContTmpl.Nb AS Templates
            FROM CONTACTS Cont
            LEFT JOIN (
          SELECT K_CONTACT, Comp.KIND, COUNT(*) AS Nb
          FROM CONT_COMP
          INNER JOIN COMPANIES Comp ON CONT_COMP.K_COMPANY=Comp.K_COMPANY
            GROUP BY K_CONTACT, Comp.KIND
        ) ContComp ON (ContComp.K_CONTACT=Cont.K_CONTACT AND KIND=12)
            LEFT JOIN (SELECT K_CONTACT, COUNT(*) AS Nb FROM CONT_CONT GROUP BY K_CONTACT) ContCont ON ContCont.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN (SELECT K_CONTACT, COUNT(*) AS Nb FROM DOCU_CONT GROUP BY K_CONTACT) ContDocu ON ContDocu.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN (SELECT K_CONTACT, COUNT(*) AS Nb FROM ACTI_CONT GROUP BY K_CONTACT) ContActi ON ContActi.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN (SELECT K_CONTACT, COUNT(*) AS Nb FROM PUBL_CONT GROUP BY K_CONTACT) ContPubl ON ContPubl.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN (SELECT K_CONTACT, COUNT(*) AS Nb FROM OPPO_CONT GROUP BY K_CONTACT) ContOppo ON ContOppo.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN (SELECT K_CONTACT, COUNT(*) AS Nb FROM MAIL_CONT GROUP BY K_CONTACT) ContMail ON ContMail.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN (SELECT K_CONTACT, COUNT(*) AS Nb FROM PROD_CONT GROUP BY K_CONTACT) ContProd ON ContProd.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN (SELECT K_CONTACT, COUNT(*) AS Nb FROM PROJ_CONT GROUP BY K_CONTACT) ContProj ON ContProj.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN (SELECT K_CONTACT, COUNT(*) AS Nb FROM PROF_CONT GROUP BY K_CONTACT) ContProf ON ContProf.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN (SELECT K_CONTACT, COUNT(*) AS Nb FROM TMPL_CONT GROUP BY K_CONTACT) ContTmpl ON ContTmpl.K_CONTACT=Cont.K_CONTACT
              ORDER BY ContComp.Nb, Cont.NAME, Cont.FIRSTNAME

  4. #4
    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
    Par défaut
    quel genre de doublons ? vous ne voulez les compter qu'une fois ? vous pouvez aussi mettre un COUNT(DISTINCT ...) dans les sous requêtes.

  5. #5
    Membre confirmé
    Homme Profil pro
    Lycéen
    Inscrit en
    Mars 2013
    Messages
    65
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Mars 2013
    Messages : 65
    Par défaut
    Bonjour,

    Désolé pour le temps de réponse.

    J'ai modifié la requête et je n'ai plus le problème de doublons, en revanche la requête me sort tous les contacts de la base de données. Je n'arrive pas à placer le "WHERE Comp.KIND=12".

    Code SQL : 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
    30
    31
    SELECT Cont.NAME AS Nom
          ,Cont.FIRSTNAME AS Prenom
          ,ContComp.Nb AS Companies
          ,ContCont.Nb AS Contacts
          ,ContDocu.Nb AS Documents
          ,ContActi.Nb AS Actions
          ,ContPubl.Nb AS Publications
          ,ContOppo.Nb AS Opportunities
          ,ContMail.Nb AS Mails
          ,ContProd.Nb AS Products
          ,ContProj.Nb AS Projects
          ,ContProf.Nb AS Profiles
          ,ContTmpl.Nb AS Templates
            FROM CONTACTS Cont
            LEFT JOIN (
              SELECT K_CONTACT, KIND, COUNT(*) AS Nb
              FROM CONT_COMP
              INNER JOIN COMPANIES Comp ON CONT_COMP.K_COMPANY=Comp.K_COMPANY
                GROUP BY K_CONTACT, Comp.KIND
            ) ContComp ON (ContComp.K_CONTACT=Cont.K_CONTACT AND KIND=12)
            LEFT JOIN (SELECT K_CONTACT, COUNT(*) AS Nb FROM CONT_CONT GROUP BY K_CONTACT) ContCont ON ContCont.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN (SELECT K_CONTACT, COUNT(*) AS Nb FROM DOCU_CONT GROUP BY K_CONTACT) ContDocu ON ContDocu.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN (SELECT K_CONTACT, COUNT(*) AS Nb FROM ACTI_CONT GROUP BY K_CONTACT) ContActi ON ContActi.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN (SELECT K_CONTACT, COUNT(*) AS Nb FROM PUBL_CONT GROUP BY K_CONTACT) ContPubl ON ContPubl.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN (SELECT K_CONTACT, COUNT(*) AS Nb FROM OPPO_CONT GROUP BY K_CONTACT) ContOppo ON ContOppo.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN (SELECT K_CONTACT, COUNT(*) AS Nb FROM MAIL_CONT GROUP BY K_CONTACT) ContMail ON ContMail.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN (SELECT K_CONTACT, COUNT(*) AS Nb FROM PROD_CONT GROUP BY K_CONTACT) ContProd ON ContProd.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN (SELECT K_CONTACT, COUNT(*) AS Nb FROM PROJ_CONT GROUP BY K_CONTACT) ContProj ON ContProj.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN (SELECT K_CONTACT, COUNT(*) AS Nb FROM PROF_CONT GROUP BY K_CONTACT) ContProf ON ContProf.K_CONTACT=Cont.K_CONTACT
            LEFT JOIN (SELECT K_CONTACT, COUNT(*) AS Nb FROM TMPL_CONT GROUP BY K_CONTACT) ContTmpl ON ContTmpl.K_CONTACT=Cont.K_CONTACT
              ORDER BY Cont.NAME, Cont.FIRSTNAME

    J'ai essayé de placer le WHERE KIND=12 tout en bas (juste au dessus du ORDER BY mais ce n'est pas bon non plus).

  6. #6
    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
    Par défaut
    quelle est la multiplicité contact-->companies ?

    que faire si un contact est rattaché a une compagnie avec KIND = 12, et une autre avec KIND = 14 ?

    En clair, que doit vous remonter la requête après filtrage sur KIND = 12 ?

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

Discussions similaires

  1. Recherche de plusieurs COUNT dans plusieurs tables
    Par Anduriel dans le forum Langage SQL
    Réponses: 8
    Dernier message: 09/07/2012, 11h15
  2. plusieurs count(*) dans une table
    Par EnRadeSurEclipse dans le forum Requêtes
    Réponses: 4
    Dernier message: 24/03/2010, 14h05
  3. Réponses: 9
    Dernier message: 19/04/2009, 15h45
  4. Count dans plusieurs colonne d'une même table
    Par macfleid dans le forum Langage SQL
    Réponses: 7
    Dernier message: 15/07/2008, 20h43
  5. Count dans plusieurs tables
    Par kevinf dans le forum Requêtes
    Réponses: 11
    Dernier message: 26/11/2006, 11h03

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