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

Requêtes et SQL. Discussion :

Problème de jointures sous Access


Sujet :

Requêtes et SQL.

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 7
    Points : 3
    Points
    3
    Par défaut Problème de jointures sous Access
    Bonjour,

    Je dois concevoir une requête pour une base Access. J'ai l'habitude de travailler avec Oracle et Mysql, mais Access semble faire la fine bouche lorsque cela devient un peu compliqué ^^

    Voici la requête que j'aimerais faire :

    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
     
    SELECT
    	`type_elt`.`Champs1` AS `symbole_type`,
    	`Machines`.`Champs1` AS `nom_machine`,
    	`type_elt`.`Champs3` AS `type_defaut`,
    	`defauts`.`Champs0` AS `adresse_defaut`,
    	`defauts`.`Champs3` AS `commentaire_defaut`,
    	`Defautsp`.`Champs0` AS `adresse_defaut_sp`,
    	`Defautsp`.`Champs3` AS `commentaire_defaut_sp`,
    	`moteur`.`Champs13` AS `entree_moteur`,
    	`moteur`.`Champs14` AS `sortie_moteur`,
    	`trappe`.`Champs12` AS `entree1_trappe`,
    	`trappe`.`Champs13` AS `entree2_trappe`,
    	`trappe`.`Champs14` AS `sortie1_trappe`,
    	`trappe`.`Champs15` AS `sortie2_trappe`,
    	`B2d`.`Champs13` AS `entree1_b2d`,
    	`B2d`.`Champs14` AS `entree2_b2d`,
    	`B2d`.`Champs15` AS `sortie1_b2d`,
    	`B2d`.`Champs16` AS `sortie2_b2d`
     
    	FROM
    	(
    		(
    			(
    				(
    					(
    						`type_elt`
     
    						LEFT JOIN `defauts`
    							ON (`defauts`.`Champs9` = `type_elt`.`Champs0`)
    					)
    					LEFT JOIN `Defautsp`
    						ON (`Defautsp`.`Champs9` = `type_elt`.`Champs0`)
    				)
    				LEFT JOIN `Machines`
    					ON (`Machines`.`Champs0` = `type_elt`.`Champs1`)
    			)
    			LEFT JOIN `moteur`
    			ON
    				(
    					(`moteur`.`Champs19` = `type_elt`.`Champs0`)
    					AND
    					(
    						(`moteur`.`Champs0` = `defauts`.`Champs1`)
    						OR (`moteur`.`Champs0` = `Defautsp`.`Champs1`)
    					)
    				)
     
    		)
    		LEFT JOIN `trappe`
    			ON
    			(
    				(`trappe`.`Champs20` = `type_elt`.`Champs0`)
    				AND
    				(
    					(`trappe`.`Champs0` = `defauts`.`Champs1`)
    					OR (`trappe`.`Champs0` = `Defautsp`.`Champs1`)
    				)
    			)
    	)
    	LEFT JOIN `B2d`
    		ON
    		(
    			(`B2d`.`Champs21` = `type_elt`.`Champs0`)
    			AND
    			(
    				(`B2d`.`Champs0` = `defauts`.`Champs1`)
    				OR (`B2d`.`Champs0` = `Defautsp`.`Champs1`)
    			)
    		)
    J'ai essayé plusieurs solutions pour faire la même chose (par exemple, enlever les "OR" et mettre plusieurs LEFT JOIN à la place) sans succès.

    Le message d'erreur est : Expression de jointure non supportée. Access me surligne la clause ON de ma jointure sur la table `moteur`.

    Merci pour votre aide

    Aurélien

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    956
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 956
    Points : 1 199
    Points
    1 199
    Par défaut
    Bonjour,
    La première chose à faire dans ta base access serait de nommer les colonnes avec des noms parlants parce que champ1,champ2 cela peut représenter des choux, des carottes, des euros ou des avions.

    Il semble que ta requête ressemble à du mysql, à ma connaissance sous access on n'encadre pas les noms de colonnes avec des `.
    On peut éventuellement, si besoin les encadrer avec des cochets [ ], ce n'est obligatoire que si ta colonne contient un caractère spécial ou un espace.


    Tu peux essayer également d'enlever toutes les () autour des left join qui nuisent à la lisibilité de la requete (étant entendu qu'access te les remettras).
    Est-ce que les colonnes de ta clause on sont bien de même type.
    A+
    Soazig

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 7
    Points : 3
    Points
    3
    Par défaut
    Salut,

    Disons que je ne maîtrise pas la structure de la base sur laquelle je dois faire cette requête, sinon j'aurais bien entendu choisi des noms plus explicites ^^

    Merci pour tes conseils, je vais essayer cela.

    --------------- edit ---------------

    Alors :

    - j'ai enlevé les "``"
    - tous les champs sont de type Texte
    - il semble que les parenthèses autours des left join soient nécessaires, sans quoi une erreur de syntaxe (opérateur absent) est levée (voir http://www.developpez.net/forums/d40...es-sql-access/)

  4. #4
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 048
    Points
    34 048
    Billets dans le blog
    14
    Par défaut
    Access écrit les jointures d'une manière horrible dont l'exemple parfait est donné dans ton message.
    J'ai essayé de remettre en forme la requête pour qu'elle soit un peu plus lisible, ça donne ça :
    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    SELECT
        `type_elt`.`Champs1` AS `symbole_type`,
        `Machines`.`Champs1` AS `nom_machine`,
        `type_elt`.`Champs3` AS `type_defaut`,
        `defauts`.`Champs0` AS `adresse_defaut`,
        `defauts`.`Champs3` AS `commentaire_defaut`,
        `Defautsp`.`Champs0` AS `adresse_defaut_sp`,
        `Defautsp`.`Champs3` AS `commentaire_defaut_sp`,
        `moteur`.`Champs13` AS `entree_moteur`,
        `moteur`.`Champs14` AS `sortie_moteur`,
        `trappe`.`Champs12` AS `entree1_trappe`,
        `trappe`.`Champs13` AS `entree2_trappe`,
        `trappe`.`Champs14` AS `sortie1_trappe`,
        `trappe`.`Champs15` AS `sortie2_trappe`,
        `B2d`.`Champs13` AS `entree1_b2d`,
        `B2d`.`Champs14` AS `entree2_b2d`,
        `B2d`.`Champs15` AS `sortie1_b2d`,
        `B2d`.`Champs16` AS `sortie2_b2d`
     
    FROM `type_elt`
    LEFT JOIN `defauts` ON `defauts`.`Champs9` = `type_elt`.`Champs0`
    LEFT JOIN `Defautsp` ON `Defautsp`.`Champs9` = `type_elt`.`Champs0`
    LEFT JOIN `Machines` ON `Machines`.`Champs0` = `type_elt`.`Champs1`
    LEFT JOIN `moteur` ON `moteur`.`Champs19` = `type_elt`.`Champs0`
      AND (
        `moteur`.`Champs0` = `defauts`.`Champs1`
        OR `moteur`.`Champs0` = `Defautsp`.`Champs1`
      )
    LEFT JOIN `trappe` ON `trappe`.`Champs20` = `type_elt`.`Champs0`
      AND (
        `trappe`.`Champs0` = `defauts`.`Champs1`
        OR `trappe`.`Champs0` = `Defautsp`.`Champs1`
      )
    LEFT JOIN `B2d` ON `B2d`.`Champs21` = `type_elt`.`Champs0`
      AND (
        `B2d`.`Champs0` = `defauts`.`Champs1`
        OR `B2d`.`Champs0` = `Defautsp`.`Champs1`
      )
    J'ai supprimé les parenthèses inutiles, tu peux déjà essayer comme ça et voir ce que ça donne parce qu'avec la collection de parenthèses d'Access, on ne s'y retrouve pas.

    Ce qui m'étonne dans la requête, ce sont les jointures justement à partir de celle avec moteur qui ont une condition de jointure sur trois tables :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    LEFT JOIN `moteur` ON `moteur`.`Champs19` = `type_elt`.`Champs0`
      AND (
        `moteur`.`Champs0` = `defauts`.`Champs1`
        OR `moteur`.`Champs0` = `Defautsp`.`Champs1`
      )
    Soit il faut 3 instances de la table moteur, soit il faut mettre la partie AND ( OR ) dans un WHERE parce que là j'ai du mal à comprendre.
    Idem pour les jointures vers `trappe` et `B2d`.

    Comme en plus les noms des colonnes ne sont pas du tout explicites (champsX), ça n'aide pas à la compréhension. On ne sait pas ce qu'est censé faire cette requête, d'autant plus qu'on ne connaît pas la structure des tables impliquées.

    Quelques conseils :
    1) Nommez vos colonnes (improprement appelées 'champs' chez Access) avec des nom sémantiquement explicites, par exemple ce que vous avez mis en AS dans le SELECT
    2) Puisque vous êtes sous Access, utilisez l'interface graphique pour construire la requête et sauvegardez là avant de la bidouiller éventuellement en SQL si elle ne répond pas parfaitement à ce que vous désirez.
    3) Sauf dans certains cas particuliers, la condition d'une jointure ne doit comporter qu'une égalité.

    Difficile d'en dire plus sur votre problème sans plus de précision de votre part.

    EDIT : Grillé par Soazig mais ma réponse complète la sienne.

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 7
    Points : 3
    Points
    3
    Par défaut
    Bonjour CinePhil, merci pour ta réponse

    J'ai déjà répondu dans l'"edit" de mon message précédent en ce qui concerne les parenthèses. Elles semblent obligatoires...

    Je vais expliquer la jointure suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    LEFT JOIN `moteur` ON `moteur`.`Champs19` = `type_elt`.`Champs0`
      AND (
        `moteur`.`Champs0` = `defauts`.`Champs1`
        OR `moteur`.`Champs0` = `Defautsp`.`Champs1`
      )
    Je veux joindre la table moteur pour chaque enregistrement lié à la table defauts OU à la table Defautsp OU les 2. Pour cela j'utilise la référence du moteur (moteur.Champs0...) qui est susceptible d'apparaître dans les colonnes Champs1 des tables défauts.

    Je vais essayer de concevoir mes jointures différemment afin d'avoir moins de conditions.

  6. #6
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 048
    Points
    34 048
    Billets dans le blog
    14
    Par défaut
    Citation Envoyé par aurel53 Voir le message
    - il semble que les parenthèses autours des left join soient nécessaires, sans quoi une erreur de syntaxe (opérateur absent) est levée (voir http://www.developpez.net/forums/d40...es-sql-access/)
    Quand je lis ça, et ce qui figurent dans l'autre discussion dont tu fournis le lien, je me dis que je ne suis pas près de refaire un truc sous Access (déjà que je n'utilise plus Winbug !) ni de le conseiller comme outil de base de données ! Je n'ose même pas appeler ce logiciel un SGDBR tellement il est peu conforme à la norme SQL.

    Enfin bref, bon courage avec la forêt de parenthèses !

  7. #7
    Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 7
    Points : 3
    Points
    3
    Par défaut
    Je dois générer des fichiers XLS à partir d'une BDD Access, elle même générée par un fichier excel

    Enfin bref... c'est pour le boulot ^^ ici les techniques n'ont pas beaucup évolué depuis 10 ans.

  8. #8
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 048
    Points
    34 048
    Billets dans le blog
    14
    Par défaut
    Citation Envoyé par aurel53 Voir le message
    Je dois générer des fichiers XLS à partir d'une BDD Access, elle même générée par un fichier excel

    Enfin bref... c'est pour le boulot ^^ ici les techniques n'ont pas beaucup évolué depuis 10 ans.
    Pauvre de toi ! Je te plains !
    J'ai eu fait ce genre de choses il y a effectivement une dizaine d'années.

  9. #9
    Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 7
    Points : 3
    Points
    3
    Par défaut
    Je vais marquer le sujet comme résolu. Je suis parti sur une approche différente, du style :

    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
     
    (
    	SELECT
    		`defauts`.`Champs0` AS `adresse_defaut`,
    		`defauts`.`Champs1` AS `symbole_element`,
    		`defauts`.`Champs3` AS `commentaire`,
    		`E_S`.`Champs6` AS `nom_machine`,
    		`defauts`.`Champs9` AS `type_element`,
    		nz(`moteur`.`Champs13`, nz(`trappe`.`Champs13`, `B2d`.`Champs13`)) AS `entree1`,
    		'' AS `entree2`,
    		nz(`moteur`.`Champs14`, nz(`trappe`.`Champs14`, `B2d`.`Champs14`)) AS `sortie1`,
    		'' AS `sortie2`
     
    		FROM
    		(
    			(
    				(
    					`defauts`
    					LEFT JOIN `E_S` ON `E_S`.`Champs2` = `defauts`.`Champs1`
    				)
    				LEFT JOIN `moteur` ON `moteur`.`Champs0` = `defauts`.`Champs1`
    			)
    			LEFT JOIN `trappe` ON `trappe`.`Champs0` = `defauts`.`Champs1`
    		)
    		LEFT JOIN `B2d` ON `B2d`.`Champs0` = `defauts`.`Champs1`
     
    		WHERE
    			`defauts`.`Champs0` <> ''
    			AND `defauts`.`Champs1` <> ''
    )
    UNION ALL
    (
    	SELECT
    		`Defautsp`.`Champs0` AS `adresse_defaut`,
    		`Defautsp`.`Champs1` AS `symbole_element`,
    		`Defautsp`.`Champs3` AS `commentaire`,
    		`E_S`.`Champs6` AS `nom_machine`,
    		`Defautsp`.`Champs9` AS `type_element`,
    		nz(`moteur`.`Champs13`, nz(`trappe`.`Champs13`, `B2d`.`Champs13`)) AS `entree1`,
    		'' AS `entree2`,
    		nz(`moteur`.`Champs14`, nz(`trappe`.`Champs14`, `B2d`.`Champs14`)) AS `sortie1`,
    		'' AS `sortie2`
     
    		FROM
    		(
    			(
    				(
    					`Defautsp`
    					LEFT JOIN `E_S` ON `E_S`.`Champs2` = `Defautsp`.`Champs1`
    				)
    				LEFT JOIN `moteur` ON `moteur`.`Champs0` = `Defautsp`.`Champs1`
    			)
    			LEFT JOIN `trappe` ON `trappe`.`Champs0` = `Defautsp`.`Champs1`
    		)
    		LEFT JOIN `B2d` ON `B2d`.`Champs0` = `Defautsp`.`Champs1`
     
    		WHERE
    			`Defautsp`.`Champs0` <> ''
    			AND `Defautsp`.`Champs1` <> ''
    )
    UNION ALL
    (
    	SELECT
    		'' AS `adresse_defaut`,
    		`E_S`.`Champs2` AS `symbole_element`,
    		`E_S`.`Champs5` AS `commentaire`,
    		`E_S`.`Champs6` AS `nom_machine`,
    		`E_S`.`Champs4` AS `type_element`,
    		'' AS `entree1`,
    		'' AS `entree2`,
    		'' AS `sortie1`,
    		'' AS `sortie2`
     
    		FROM
    			`E_S`
     
    		LEFT JOIN `Machines` ON `Machines`.`Champs0` = `E_S`.`Champs4`
     
    		WHERE
    			`E_S`.`Champs2` <> ''
    )
    Non, ce n'est pas exactement équivalent Dans la première version, j'utilisais une table qui finalement, n'est pas utile (je peux trouver toutes les infos dans les autres tables) ce qui limite la complexité des jointures.
    Au lieu de mes jointures conditionnelles compliquées, j'ai utilisé des unions, ce qui n'est pas aussi propre (et sans doute moins bon au niveau des performances). Mais bon, au moins ça semble faisable sous Access.

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

Discussions similaires

  1. [AC-2010] Problème de jointure sous Access 2010
    Par a.aiouaz dans le forum Access
    Réponses: 2
    Dernier message: 07/09/2012, 09h16
  2. Problème de requête sous Access
    Par david71 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 08/06/2007, 17h47
  3. [SQL]Problème requete sql sous access avec vba
    Par aaliyan dans le forum Requêtes et SQL.
    Réponses: 8
    Dernier message: 13/04/2007, 18h53
  4. Problème de requêtes sous Access
    Par guestCam dans le forum Access
    Réponses: 2
    Dernier message: 02/03/2007, 15h56
  5. requete et jointure sous access
    Par sapic dans le forum Access
    Réponses: 4
    Dernier message: 03/04/2006, 12h21

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