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 :

Group by, jointure, élément vide


Sujet :

Langage SQL

  1. #1
    Tan
    Tan est déconnecté
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 168
    Points : 158
    Points
    158
    Par défaut Group by, jointure, élément vide
    Bonjour,
    je suis sous access 2000, mais je pense que la question est d'ordre générale SQL.

    J'ai pour simplifier 2 tables que je joins grâce à un INNER JOIN.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
         Table1     |   Table2    |       Résultat           |     Voulu
    ------------------------------------------------------------------------------
    clé1     lien   |    clé2     |   clé1   count(clé1)     | clé1    count(clé1)
    1          4    |     1       |    1           1         |  1           1
    1          5    |     3       |    2           2         |  2           2
    1          6    |     6       |                          |  4           0 
    2          1    |     7       |
    2          3    |
    4          7    |
    Je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT cle1, count(cle1) 
    FROM table1 INNER JOIN table2 ON table1.lien = table2.cle2
    WHERE table1.cle2 IN (1, 3, 6)
    GROUP BY cle1
    Donc cet exemple, pour cle1 = 4, il n'y a pas d'élément qui vérifie la condition WHERE, donc pas de lien, il n'a pas de résultat dans la requête.
    Je souhaiterai avoir un résultat (0 serait bien)

    En fais je veux pour chaque élément de:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT cle1 FROM table1 group by cle1
    Il y ait une correspondance. J'arrive à contourner mon problème par des requêtes immenses, mais je pense, qu'il y a un moyen auquel je ne pense pas actuellement, qui pourrais résoudre mon problème beaucoup plus simplement.

    Peux être qu'un LEFT OUTER JOIN avec le SELECT cle1 FROM table1 pourrait m'aider, mais est-ce la seule solution.

    Je cherche à faire quelque chose de pas trop lourd.
    Merci, d'avance.

  2. #2
    Expert confirmé

    Profil pro
    Inscrit en
    Avril 2002
    Messages
    3 338
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 338
    Points : 4 657
    Points
    4 657
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT Table1.cle1, Count(Table2.Cle2) AS CompteDeCle2
    FROM Table1 LEFT JOIN Table2 ON Table1.Lien = Table2.Cle2
    GROUP BY Table1.cle1;
    Ton exemple est faux, cle1=4 avec Lien=7 à bien une correspondance dans la table2.

  3. #3
    Tan
    Tan est déconnecté
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 168
    Points : 158
    Points
    158
    Par défaut
    La clé1 = 4 a bien une correspondance, mais la condition WHERE l'élimine.
    Et donc, clé1 = 4 n'apparait pas dans les résultats (moi, je voudrais qu'il y ai 0 à la place, donc écrire la requête différemment pour cela.
    En ce moment, je cherche, mais je peine un peu sur truc là.

  4. #4
    Expert confirmé

    Profil pro
    Inscrit en
    Avril 2002
    Messages
    3 338
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 338
    Points : 4 657
    Points
    4 657
    Par défaut
    Pour quelle raison tu veux qu'il y ai 0 ?
    qu'est ce qui différencie cle1 = 4 et cle1=1 ?

    si tu veux des règles de gestion différentes pour 2 valeurs distinctes, il doit te manquer un discriminant quelque part.

  5. #5
    Membre actif
    Inscrit en
    Février 2003
    Messages
    182
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 182
    Points : 206
    Points
    206
    Par défaut
    tu peux faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    SELECT cle1, count(cle1) as nb_cle 
    FROM table1 INNER JOIN table2 
    ON table1.lien = table2.cle2 
    WHERE table2.cle2 IN (1, 3, 6) 
    GROUP BY cle1
    union
    SELECT distinct cle1, 0 as nb_cle 
    FROM table1 
    WHERE table1.lien not IN (1, 3, 6)
    A+

  6. #6
    Tan
    Tan est déconnecté
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 168
    Points : 158
    Points
    158
    Par défaut
    Pour Gaël:
    Petit exemple du but de la manoeuvre, (je m'y prend peut être mal).
    - Les éléments de table1 serait des règles de validation
    - Les éléments de table2 les conditions liées au règles.

    Je voudrais récupérer tous les éléments qui satisfassent au moins un certain nombre de condition.

    Je veux donc le nombre de conditions vérifiées (les conditions sont mis dans le IN).
    Dans mon exemple je veux savoir combien de condition sont vérifiées pour chaque règle parmi les conditions 1, 3 et 6.

    Dans l'exemple:
    - pour la règle 1, 1 seule est vérifiée
    - pour la 2, 2
    - pour la 3 rien car cette règle n'existe pas.
    - pour la 4, 0 condition sont vérifiées

    Donc, après je pourrais dire que la règle 4 et la 1 ne sont pas bonnes, car elle vérifient moins de 2 condition (ça s'est une condition que je rajouterai après)
    Si je regarde ce que j'ai dans "résultat" (voir l'exemple), je trouve que seulement 1 est inférieur à 2. Je ne sais pas que 4 égale 0 car ce n'est pas affiché. (ce qui ai affiché dans "voulu")

    Voilà, pour résumer, je veux faire la différence entre 0 (parce que rien n'est vérifié) et rien parce n'existe pas.

    Ca parait un peut bidon de faire ça, mais j'ai simplifié pour expliquer (imagines ce que dnneraient mes explications sinon)

    Pour MAMAR:
    J'ai pensé à un truc comme ça, mais ça me parait lourd, car il faut rajouter pour la seconde partie de l'UNION, une condition pour vérifier que les 3 conditions ne sont pas vérifié et pas l'une des trois.
    Pour ta requête, j'arai comme résultat (je pense)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Clé1     count
     1        1
     2        2
     1        0
     2        0
     4        0
    Ce qui n'est pas le résultat souhaité.
    Sachant que j'ai simplifié le problème, et qu'il faut encore rajouter des sous requête pour bien vérifier ce que je veux, ça fini par faire une requête très compliqué.

    Je pense, qu'on peut faire plus simple. Enfin j'espère, sinon tampis, je ferai aveec.

    Merci en tout cas

  7. #7
    Membre actif
    Inscrit en
    Février 2003
    Messages
    182
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 182
    Points : 206
    Points
    206
    Par défaut
    Ma première solution demandait de refaire la jointure dans le second membre de l'union avec la nouvelle restriction

    ceci est plus simple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT cle1, count(cle2)  
    FROM table1  Left JOIN table2 
    ON table1.lien = table2.cle2 
    WHERE ( table2.cle2 IN (1, 3, 6) or table2.cle2 is null) 
    GROUP BY cle1
    A+

  8. #8
    Tan
    Tan est déconnecté
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 168
    Points : 158
    Points
    158
    Par défaut
    Je testerai cette solution demain, et je vous tiens au courant.
    Si ca marche super, sinon, la piste est bonne quand même.

  9. #9
    Tan
    Tan est déconnecté
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 168
    Points : 158
    Points
    158
    Par défaut
    Salut,
    Je viens de tester, et je trouve le même résultat que j'ai mis dans "résultat" (voir l'exemple)
    Mais, je vais tenter de modifier ta méthode, pour trouver un bon résultat

  10. #10
    Membre actif
    Inscrit en
    Février 2003
    Messages
    182
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 182
    Points : 206
    Points
    206
    Par défaut
    supprimons la clause where et faisons ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT cle1, count(iif(cle2 IN (1, 3, 6),cle2,null))  
    FROM table1  Left JOIN table2 
    ON table1.lien = table2.cle2 
    GROUP BY cle1
    A+

  11. #11
    Tan
    Tan est déconnecté
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 168
    Points : 158
    Points
    158
    Par défaut
    Voici, une requête qui me donne les bons résultats:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT cle1, sum(count) as nbVerif 
    FROM
             (SELECT cle1,
                     IIf((cle2 =1 or cle2 = 3 or cle2 =6),1, 0) AS count 
             FROM table1 INNER JOIN table2 ON table1.lien = table2.cle2
             WHERE cle2 In (1,3,6) OR cle2 Not In (1,3,6))
    GROUP BY cle1
    Je la trouve un peu tordue, mais bon, je pense que je vais faire avec.
    Je réfléchi encore un peu, puis je mettrai résolu.

  12. #12
    Tan
    Tan est déconnecté
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 168
    Points : 158
    Points
    158
    Par défaut
    Bien, MAMAR, je ne savais pas que le IN marchait dans le iif.
    J'avais essayé en plus, en me disant on ne sais jamais, mais j'avais dû faire une faute, de frappe.
    Donc, ta méthode me plait plus.
    Je vais l'adapter à mon cas, et ce sera bon.
    Merci.

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

Discussions similaires

  1. [xml + xsl] détection d'élément vide
    Par tut dans le forum XSL/XSLT/XPATH
    Réponses: 20
    Dernier message: 11/05/2007, 10h44
  2. StrinkTokenizer : récupérer les éléments "vides"
    Par Yannick_from_31 dans le forum Langage
    Réponses: 3
    Dernier message: 21/08/2006, 10h29
  3. Connaitre un élément vide
    Par thierry337 dans le forum XSL/XSLT/XPATH
    Réponses: 3
    Dernier message: 14/03/2006, 08h51
  4. Réponses: 7
    Dernier message: 20/11/2005, 19h26
  5. Supprimé des éléments vide d'un tableau
    Par shinux2004 dans le forum Langage
    Réponses: 4
    Dernier message: 04/07/2005, 19h40

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