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

VBA Access Discussion :

Requete: Jointure de 2 tables en 3 champs seulement si VALEURS de champs réparties sur n lignes correspondent


Sujet :

VBA Access

  1. #1
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 96
    Points : 47
    Points
    47
    Par défaut Requete: Jointure de 2 tables en 3 champs seulement si VALEURS de champs réparties sur n lignes correspondent
    Bonsoir à tous les membres,
    Je viens de me rendre compte d'une analyse erronée suite à une erreur de ma part sur les vertus des jointures dans ACCESS (100% ma faute).
    J'ai une table_1 avec 4 champs
    C1, C2, C3, C4
    01,AB,04, Blabla

    et une table_2 avec 3 champs
    D1, D2, D3
    01,02,02
    01, AZ, 04

    Je joins ces deux tables en reliant : C1 à D1, C2 à D2 et C3 à D3 en obtenant une table finale avec les 4 champs C*. La table_2 agissant comme un filtre en réalité.
    Je pensais qu'ACCESS allait résonner selon : "il faut que les 3 jointures correspondent pour que ma requête donne un résultat".
    En fait, après test, ce n'est pas tout à fait vrai. Des lors qu'une jointure est vraie, par exemple C1 correspond bien à une valeur D1, alors ma requête alimente une ligne. Tant pis si C2 ne correspond pas à D2 ou C3 à D3.
    Est-il possible d'influencer ACCESS pour qu'il prenne en compte la combinaison des 3 jointures pour exécuter la requête ? c'est à dire que dans mon exemple, la requête ne donne rien comme résultat car, certes C1 correspond à D1, mais jamais C2 ne correspond à D2 par exemple.

    Merci pour votre aide.

    Amicalement,
    David

  2. #2
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 617
    Points : 56 731
    Points
    56 731
    Billets dans le blog
    40
    Par défaut
    bonsoir,

    Citation Envoyé par dagada75 Voir le message
    Je pensais qu'ACCESS allait raisonner selon : "il faut que les 3 jointures correspondent pour que ma requête donne un résultat".
    En fait, après test, ce n'est pas tout à fait vrai.
    Étonnant !! Cependant il faut que les jointures soient de type "1", c'est bien le cas ?

  3. #3
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 96
    Points : 47
    Points
    47
    Par défaut
    Il s'agit bien de 3 jointures de type "1". Oui

  4. #4
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 96
    Points : 47
    Points
    47
    Par défaut
    Voici mon exemple, cas concret, ... est-ce que je fais une erreur quelque part ??
    Table_1
    User;OBJECT;FIELD;LOW
    T01;S_PROJECT; APPL_COMP;*
    T01;S_PROJECT; APPL_COMP ;01
    T01;S_PROJECT; APPL_COMP ;02
    T01;S_PROJECT; APPL_COMP ;03
    T01;S_PROJECT; APPL_COMP ;05
    T01;S_PROJECT; APPL_COMP ;23
    T01;S_PROJECT; ACTVT;03
    T01;S_PROJECT; APPL_COMP;*
    T01;MAINTAIN PROJECT;S_TCODE; TCD; SPRO_ADMIN

    Table_2
    strActivity;strObject ;strField;strValue
    MAINTAIN PROJECT; S_PROJECTS; ACTVT; 01
    MAINTAIN PROJECT; S_PROJECTS; APPL_COMP; *
    MAINTAIN PROJECT;S_TCODE; TCD; SPRO_ADMIN
    MAINTAIN PROJECT; S_PROJECT; PRCLASS; *

    Je joins OBJECT à strObject, FIELD à strField et LOW à strValue. Jointure de type 1.

    Résultat de ma requête est:
    USER; OBJECT; FIELD; LOW; strActivity
    T01; S_PROJECTS; APPL_COMP; *; MAINTAIN PROJECT
    T01; S_TCODE ;TCD ;SPRO_ADMIN ;MAINTAIN PROJECT

    Alors que je m'attendais à zero résultat car les "lignes de donnée suivantes" en Table_2 ne trouve pas de correspondance en Table_1:
    MAINTAIN PROJECT; S_PROJECTS; ACTVT; 01
    MAINTAIN PROJECT; S_PROJECT; PRCLASS; *

  5. #5
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 96
    Points : 47
    Points
    47
    Par défaut
    A travers mon exemple concret je me suis rendu compte que la requête d'ACCESS donne logiquement un résultat car, effectivement, il y a correspondance dans les 2 tables pour:
    T01; S_PROJECTS; APPL_COMP; *; MAINTAIN PROJECT
    T01; S_TCODE ;TCD ;SPRO_ADMIN ;MAINTAIN PROJECT

    Alors comment faire pour que la requête effectue l'analyse suivante:
    "pour obtenir une correspondance avec la valeur de champ 'MAINTAIN PROJECT' de la table_2, il faut impérativement réunir les '4 conditions suivantes' à travers les 3 derniers champs.
    MAINTAIN PROJECT; S_PROJECTS; ACTVT; 01
    +
    MAINTAIN PROJECT; S_PROJECTS; APPL_COMP; *
    +
    MAINTAIN PROJECT;S_TCODE; TCD; SPRO_ADMIN
    +
    MAINTAIN PROJECT; S_PROJECT; PRCLASS; *

    La jointure n'est peut-être pas la solution en fait ?

    Amclt,
    David

  6. #6
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 96
    Points : 47
    Points
    47
    Par défaut
    J'essaie de contourner le problème avec une jointure de non correspondance mais cela ne marche pas non plus...
    L'idée est d'ajouter un autre champ 'Group n°' à ma table_2 afin d'indiquer que les "4 lignes" dont les valeurs des champs strObject ;strField;strValue de ma tables_2 sont requises, en y associant le meme 'Group n°' = '01' à ces 4 lignes.
    Si j'arrive à "exclure" ne serait-ce qu'une ligne qu'on ne retrouve pas dans ma table_1, ici par exemple:
    MAINTAIN PROJECT; S_PROJECTS; ACTVT; 01
    MAINTAIN PROJECT; S_PROJECT; PRCLASS; *
    Alors j'ajoute au résultat de ma query le champ 'Group n°' et je peux en tirer la conclusion suivante:
    Dès lors que ma requete me livre qu'une ligne avec un 'Group n°', toutes les conditions requises (lignes+valeur de champ) de la table_2 ne sont pas réunies dans la table_1.
    J'essaie avec les LEFT JOIN et les conditions WHERE mais je n'ai pas le résultat souhaité.

    david

  7. #7
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 96
    Points : 47
    Points
    47
    Par défaut
    Je pensai atteindre au but en produisant le code suivant AGR_1251_Y_MERGE_finale_star.UNAME est ma table_1 et [Copie de SOD_Tb_Activity] est ma table_2 et en n'affichant que les colonnes WHERE '<>'

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT DISTINCT AGR_1251_Y_MERGE_finale_star.UNAME, [Copie de SOD_Tb_Activity].strObject, [Copie de SOD_Tb_Activity].strField, [Copie de SOD_Tb_Activity].strValue, [Copie de SOD_Tb_Activity].strGroup
    FROM AGR_1251_Y_MERGE_finale_star INNER JOIN [Copie de SOD_Tb_Activity] ON AGR_1251_Y_MERGE_finale_star.SYSTEM = [Copie de SOD_Tb_Activity].strSystem
    WHERE (((AGR_1251_Y_MERGE_finale_star.UNAME) Like "TSD01") AND (([Copie de SOD_Tb_Activity].strObject)<>[AGR_1251_Y_MERGE_finale_star].[OBJECT]) AND (([Copie de SOD_Tb_Activity].strField)<>[AGR_1251_Y_MERGE_finale_star].[FIELD]) AND (([Copie de SOD_Tb_Activity].strValue)<>[AGR_1251_Y_MERGE_finale_star].[LOW]))
    ORDER BY AGR_1251_Y_MERGE_finale_star.UNAME;
    Pour autant, le résultat de ma requete contient effectivement le resultat escompté (une ligne de table_2 non contenu dans table_1) MAIS aussi des données sans cohérence puisque la table_1 et le user 'TSD01' possèdent bel et bien les mêmes données ?

    Un diagnostic pour m'aiguiller SVP ?
    Merci
    David

  8. #8
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 617
    Points : 56 731
    Points
    56 731
    Billets dans le blog
    40
    Par défaut
    Je diagnostique un mal de crâne à celui qui essaiera de décrypter ce que tu souhaites depuis 3-4 posts. Toutefois je peux me tromper, il y a plein de gens talentueux sur ce forum

    Pour ma part, j'ai ouvert le tube d'aspro à ce moment là:
    il faut impérativement réunir les '4 conditions suivantes' à travers les 3 derniers champs.

  9. #9
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 96
    Points : 47
    Points
    47
    Par défaut
    Bonsoir Fabien,
    Tu as raison désolé. Ce qui est clair dans ma tête ne l'est pas dans mes propos.
    En fait j'essaie d'établir une correspondance stricte entre 2 tables (exclusion) ou, à défaut, identifier les non-correspondances.
    Simplifions mon exemple.
    Je dispose d'une table_1 avec des données clients (lignes) avec plusieurs propriétés (colonnes)
    Client, Propriété1,Propriété2,Propriété3
    David, A, B, C
    David, B, Z, D
    Ludo, A, B, Z

    Et je dispose d'une table_2 disons "d'éligibilité" qui répond à plusieurs conditions.
    Ainsi, pour répondre à l'éligibilité '01' il faut répondre aux 2 conditions (lignes dans ma table_2) ci-dessus.

    Eligibilité, Propriété1, Propriété2, Propriété3
    01,A, B, C
    01, B, Z, A

    Le but de ma requête serait de connaitre les clients "éligibles" soit:
    1) en me donnant un résultat nul car aucun client ne répond favorablement à toutes les conditions de l'éligibilité '01' (ici le client DAVID s'en rapproche mais pas sur la condition B, Z, A car il possède la valeur D au lieu de A)
    2) en me donnant le résultat UNIQUEMENT DE CE QUI NE CORRESPOND PAS entre les 2 tables, ici
    Clients, Eligibilité, Propriété1, Propriété2, Propriété3
    David, 01, B, Z, A
    Ludo, 01, A, B, C
    Ludo, 01, B, Z, A

    Car ainsi je sais que les clients ont au moins une condition non éligible à "01" DONC je peux logiquement les exclure a posteriori.

    J'espère que c'est plus clair

    David

  10. #10
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 617
    Points : 56 731
    Points
    56 731
    Billets dans le blog
    40
    Par défaut
    bonsoir,

    voui, c'est plus clair maintenant
    Enfin je crois, je garde le tube d'aspro sous la main...

    Voici une proposition sur l'exemple simplifié :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT table_1.client,
           table_2.Eligibilite
    FROM   table_1
           INNER JOIN table_2
                   ON ( table_1.p1 = table_2.p1
                        AND table_1.p2 = table_2.p2
                        AND table_1.p3 = table_2.p3 )
    GROUP  BY table_1.client,
              table_2.Eligibilite
    HAVING Count(*) = (SELECT Count(*)
                       FROM   table_2 AS U
                       WHERE  U.Eligibilite = table_2.Eligibilite);

    Elle est sensée retourner les clients et ce à quoi il sont éligibles.

  11. #11
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 96
    Points : 47
    Points
    47
    Par défaut
    Merci.
    Ca semble fonctionner !!
    J'approfondis mes tests avec des cas tordus (tube d'Aspirine) et je pourrai mettre un statut "résolu" !
    Merci de m'avoir consacré du temps Fabien. C'est vraiment généreux de votre part à vous tous contributeurs de ce forum.
    David

  12. #12
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 96
    Points : 47
    Points
    47
    Par défaut
    Alors cela fonctionne parfaitement dans le cas où j'ai une seule condition d'éligibilité par ligne dans ma table_2.
    Par contre, dans le cadre de mon exemple simplifié, l'éligibilité '01' répond à 2 conditions (2 lignes dans table_2) et, meme si le client répond favorablement à ces 2 conditions, je n'obtiens aucun résultat.
    David

  13. #13
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 617
    Points : 56 731
    Points
    56 731
    Billets dans le blog
    40
    Par défaut
    Bonjour David,

    dans le cadre de mon exemple simplifié, l'éligibilité '01' répond à 2 conditions (2 lignes dans table_2) et, meme si le client répond favorablement à ces 2 conditions, je n'obtiens aucun résultat.
    Pourtant...
    Images attachées Images attachées  

  14. #14
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 96
    Points : 47
    Points
    47
    Par défaut
    Dans cet exemple, tu comprendras que la 1ere table est un extrait de ma table_1 avec UNAME en guise de "Client"
    La deuxième table est la table_2 avec strGroup en guise de 'Eligibilité"
    ET la troisième table est le résultat de ma requete.
    On es d'accord que je devrai retrouvé le StrGroup '01' car le UNAME 'TSD01' répond bien aux 2 conditions non ?
    Images attachées Images attachées  

  15. #15
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 96
    Points : 47
    Points
    47
    Par défaut
    Le code me semble conforme à tes conseils.

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT [Copie de AGR_1251_Y_MERGE_finale_star].UNAME, [Copie de SOD_Tb_Activity].strGroup, [Copie de SOD_Tb_Activity].strObject, [Copie de SOD_Tb_Activity].strField, [Copie de SOD_Tb_Activity].strValue
    FROM [Copie de AGR_1251_Y_MERGE_finale_star] INNER JOIN [Copie de SOD_Tb_Activity] ON ([Copie de AGR_1251_Y_MERGE_finale_star].LOW = [Copie de SOD_Tb_Activity].strValue) AND ([Copie de AGR_1251_Y_MERGE_finale_star].FIELD = [Copie de SOD_Tb_Activity].strField) AND ([Copie de AGR_1251_Y_MERGE_finale_star].OBJECT = [Copie de SOD_Tb_Activity].strObject)
    GROUP BY [Copie de AGR_1251_Y_MERGE_finale_star].UNAME, [Copie de SOD_Tb_Activity].strGroup, [Copie de SOD_Tb_Activity].strObject, [Copie de SOD_Tb_Activity].strField, [Copie de SOD_Tb_Activity].strValue
    HAVING (((Count(*))=(SELECT Count(*)
    FROM  [Copie de SOD_Tb_Activity] AS U
    WHERE  U.strGroup = [Copie de SOD_Tb_Activity].strGroup)));

  16. #16
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 96
    Points : 47
    Points
    47
    Par défaut
    C'est quand meme très curieux non ...?
    Images attachées Images attachées  

  17. #17
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 617
    Points : 56 731
    Points
    56 731
    Billets dans le blog
    40
    Par défaut
    bonsoir,

    à mon avis il y a trop de monde dans le GROUP BY :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    GROUP BY [Copie de AGR_1251_Y_MERGE_finale_star].UNAME, 
             [Copie de SOD_Tb_Activity].strGroup, 
             [Copie de SOD_Tb_Activity].strObject,
             [Copie de SOD_Tb_Activity].strField,
             [Copie de SOD_Tb_Activity].strValue
    HAVING ...

    Il faut grouper par UNAME et strGroup seulement.
    Essaie en supprimant les autres champs dans le GROUP BY et dans le SELECT.

  18. #18
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 96
    Points : 47
    Points
    47
    Par défaut
    Bonjour Fabien,
    J'ai suivie tes conseils .. mais je crois qu'il y a un problème avec la présence ou non de CHIFFRES dans la table_2.
    Tu penses que cela vient de là ? Je dois influencer ma table sur le type des champs ?

    David

    ps: on se rapproche de la solution
    Images attachées Images attachées  

  19. #19
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 617
    Points : 56 731
    Points
    56 731
    Billets dans le blog
    40
    Par défaut
    bonjour David,

    Ha oui, ça ne marche pas avec strGroup="05" on dirait

    tous tes champs sont de type "texte" avec des valeurs de type chaîne de caractères comme "100", "101", etc.

    Par contre ta table provient d'un import de je ne sais où donc il est possible que le contenu ne soit pas très propre avec des caractères <espace> ou autres caractères spéciaux invisibles à l'écran (quand je vois des "µµ").

    Essaie en ressaisissant à la main tes valeurs "01", "02",..., "100",... dans les deux tables.

  20. #20
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2012
    Messages : 96
    Points : 47
    Points
    47
    Par défaut
    Merci Fabien mais il s'agissait déjà d'entrées manuelles
    Les caractères "µµ" étaient volontaires pour tester la requete ET elle s'en est très bien sortie !!
    Par contre le fait qu'elle ne reconnaisse pas le group '05' dépasse mon entendement.. j'ai multiplié les tests ... avec uniquement des chiffres, mixte chiffres caractères, caractères ...
    Ca passe et dès fois ça ne passe pas ..

    Il s'agit bien de champs TEXTE.
    David
    Images attachées Images attachées  

Discussions similaires

  1. Réponses: 7
    Dernier message: 01/04/2014, 14h45
  2. Réponses: 3
    Dernier message: 20/09/2013, 10h07
  3. Réponses: 1
    Dernier message: 03/05/2007, 08h10
  4. Requete jointure de 2 tables
    Par mickey45 dans le forum Requêtes
    Réponses: 4
    Dernier message: 01/12/2006, 12h48
  5. Réponses: 5
    Dernier message: 06/06/2006, 14h12

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