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 :

Jointures multiples en SQL


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 21
    Par défaut Jointures multiples en SQL
    Bonjour,

    Suite à la migration d'une base ACCESS vers SQL Server, je suis un peu perdu avec le langage SQL (appris il y a une dizaine d'année, mais pas ou peu utilisé depuis), et les jointures multiples.

    J'ai créé la requête ACCESS suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT OCEAN_ADM_CELLULE.CELL_ID, OCEAN_ADM_MODRADIO.MRAD_REF
    FROM (OCEAN_ADM_SITE INNER JOIN OCEAN_ADM_BAIE ON OCEAN_ADM_SITE.SIT_ID = OCEAN_ADM_BAIE.SIT_ID) INNER JOIN (OCEAN_ADM_CELLULE INNER JOIN (OCEAN_ADM_CONFBAIE INNER JOIN OCEAN_ADM_MODRADIO ON (OCEAN_ADM_CONFBAIE.MRAD_ID = OCEAN_ADM_MODRADIO.MRAD_ID) AND (OCEAN_ADM_CONFBAIE.SYS_ID = OCEAN_ADM_MODRADIO.SYS_ID)) ON (OCEAN_ADM_CELLULE.SYS_ID = OCEAN_ADM_MODRADIO.SYS_ID) AND (OCEAN_ADM_CELLULE.CTR_ID = OCEAN_ADM_MODRADIO.CTR_ID)) ON OCEAN_ADM_BAIE.BAI_ID = OCEAN_ADM_CONFBAIE.BAI_ID
    WHERE (((OCEAN_ADM_CELLULE.CTR_ID)=6))
    GROUP BY OCEAN_ADM_CELLULE.CELL_ID, OCEAN_ADM_MODRADIO.MRAD_REF;
    Nom : Requête.png
Affichages : 4185
Taille : 75,2 Ko

    Comment traduire cela en SQL pour SQL Server ?

    En relisant mes cours sur le language SQL, je comprend bien comment créer une jointure entre 2 tables.
    Mais lorsque il y a plusieurs jointures vers la même table qui elle même comporte plusieurs jointures vers une autre table, là je suis perdu.
    Y a-t-il une astuce pour faciliter l'écriture du code ?


    Merci pour votre aide

  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,

    globalement, les "astuces" sont toujours les même et somme toute assez basiques :
    1/ indentation
    2/ utilisation des alias
    3/ suppression du superflu (comme les parenthéses dans votre cas)

    ce qui donne avec votre requete :

    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
     
    SELECT 
    		Cel.CELL_ID
    	,	Mo.MRAD_REF
    FROM		OCEAN_ADM_SITE sit
    INNER JOIN	OCEAN_ADM_BAIE bai
    		ON		sit.SIT_ID = bai.SIT_ID
    INNER JOIN	OCEAN_ADM_CELLULE Cel
    			INNER JOIN OCEAN_ADM_CONFBAIE conf
    						INNER JOIN OCEAN_ADM_MODRADIO Mo
    								ON			conf.MRAD_ID = Mo.MRAD_ID 
    								AND			conf.SYS_ID = Mo.SYS_ID 
    					ON		Cel.SYS_ID = Mo.SYS_ID 
    					AND		Cel.CTR_ID = Mo.CTR_ID 
    		ON		bai.BAI_ID = conf.BAI_ID
    WHERE	Cel.CTR_ID=6
    GROUP BY 
    			Cel.CELL_ID
    		,	Mo.MRAD_REF
    ;

  3. #3
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 995
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 995
    Billets dans le blog
    6
    Par défaut
    Access rajoute des tonnes de parenthèses totalement farfelues et pour certaines (notamment jointures) totalement incompréhensible. Débarrassez vous de l'écriture automatique des requêtes via le gadget visuel d'accès et écrivez vos propres requêtes sous forme textuelle !

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 21
    Par défaut Merci pour vos réponses
    Merci pour vos réponses.
    Je suis d'accord, ACCESS rajoute des tonnes de parenthèses et utilise son propre code SQL.

    OK pour les alias.
    J'ai aussi remarqué que l'on peux utiliser le JOIN sans le INNER
    Ce qui me perturbe dans vos réponses c'est que aieeeuuuuu imbrique les INNER JOIN et met ensuite les condition ON, alors que ce n'est pas le cas de hmira.
    Les 2 codes sont équivalents ?

  5. #5
    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
    Citation Envoyé par kennely Voir le message
    J'ai aussi remarqué que l'on peux utiliser le JOIN sans le INNER
    En effet, INNER est facultatif (par défaut).

    Citation Envoyé par kennely Voir le message
    Ce qui me perturbe dans vos réponses c'est que aieeeuuuuu imbrique les INNER JOIN et met ensuite les condition ON, alors que ce n'est pas le cas de hmira.
    Les 2 codes sont équivalents ?
    J'ai en effet gardé la structure initiale de votre requete.
    Dans le cas de jointures internes uniquement, c'est équivalent, et je trouve l'écriture d'hmira bien plus lisible (notamment car la condition de jointure suit directement la table jointe...). Cette écriture est d'ailleurs nettement plus courante, et de surcroit, rien ne vous empêche d'indenter les jointures pour une meilleur lisibilité de l'arborescence, sans pour autant imbriquer les jointures :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    SELECT ...
    FROM CLIENT C
    INNER JOIN COMMANDE C
        ON C.cli_id = C.cli_id
                INNER JOIN COMMANDE_DETAIL CD
                    ON CD.cmd_id = C.cmd_id
    INNER JOIN PAIEMENT P
        ON P.cli_id = C.cli_id
                INNER JOIN PAIEMENT_DETAIL PD
                    ON PD.pai_id = P.pai_id
    L'imbrication des jointures devient cependant utile en cas de jointure externe. Si dans l'exemple ci dessus, vous supposez qu'un client peut ne pas avoir de commande et qu'il peut ne pas avoir de paiement (mais que vous voulez malgré tout garder ces clients dans le résultat de la requête) vous pouvez passer toutes les jointures en jointure externe, ou bien écrire comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    SELECT ...
    FROM CLIENT C
    LEFT JOIN COMMANDE C
                INNER JOIN COMMANDE_DETAIL CD
                    ON CD.cmd_id = C.cmd_id
        ON C.cli_id = C.cli_id
    LEFT JOIN PAIEMENT P
                INNER JOIN PAIEMENT_DETAIL PD
                    ON PD.pai_id = P.pai_id
        ON P.cli_id = C.cli_id

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 21
    Par défaut
    aieeeuuuuu, merci pour ces précisions.
    En effet, je trourve aussi le code d'hmira plus lisible.
    C'est ACCESS qui a créé ces imbrications.

    Grâce à vos explications (à tout les deux), j'ai pu créer ma requête que j'ai utilisé dans une requête mise à jour avec une instruction CASE.
    Pour me remettre dans le bain, pourriez-vous me conseiller un livre de référence sur le code SQL ?

  7. #7
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2003
    Messages
    733
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2003
    Messages : 733
    Billets dans le blog
    8
    Par défaut
    Cette syntaxe de Microsof Access n'a plus cours et, à ma connaissance n'a même jamais eu cours sous SQL Server ! Il faut respecter désormais la norme SQL

    Sous SQL Server, votre requête doit être réécrite comme suit :

    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
    SELECT OCEAN_ADM_CELLULE.CELL_ID, OCEAN_ADM_MODRADIO.MRAD_REF
    FROM OCEAN_ADM_SITE 
    INNER JOIN OCEAN_ADM_BAIE 
      ON OCEAN_ADM_SITE.SIT_ID = OCEAN_ADM_BAIE.SIT_ID
    INNER JOIN OCEAN_ADM_CONFBAIE 
      ON OCEAN_ADM_BAIE.BAI_ID = OCEAN_ADM_CONFBAIE.BAI_ID 	
    INNER JOIN OCEAN_ADM_MODRADIO 
      ON  OCEAN_ADM_CONFBAIE.MRAD_ID = OCEAN_ADM_MODRADIO.MRAD_ID 
      AND OCEAN_ADM_CONFBAIE.SYS_ID = OCEAN_ADM_MODRADIO.SYS_ID	
    INNER JOIN OCEAN_ADM_CELLULE 
      ON  OCEAN_ADM_CELLULE.SYS_ID = OCEAN_ADM_MODRADIO.SYS_ID
      AND OCEAN_ADM_CELLULE.CTR_ID = OCEAN_ADM_MODRADIO.CTR_ID
    WHERE OCEAN_ADM_CELLULE.CTR_ID = 6
    GROUP BY OCEAN_ADM_CELLULE.CELL_ID, OCEAN_ADM_MODRADIO.MRAD_REF;

    A+

    PS : Je n'avais pas vu la réponse de aieeeuuuuu !

Discussions similaires

  1. Requete SQL avec jointure multiple
    Par kissskoool dans le forum Langage SQL
    Réponses: 5
    Dernier message: 20/01/2008, 01h07
  2. [SQL 2000] Optimisation requête avec jointure multiple
    Par zooffy dans le forum Développement
    Réponses: 5
    Dernier message: 18/09/2007, 15h38
  3. [SQL 2000] Optimisation requête avec jointure multiple
    Par zooffy dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 18/09/2007, 15h38
  4. Jointures externes multiples en SQL ACCESS
    Par philnext dans le forum Langage SQL
    Réponses: 3
    Dernier message: 08/09/2007, 16h53
  5. [PostGre SQL] Jointure multiples impossible
    Par Montaigne dans le forum Langage SQL
    Réponses: 8
    Dernier message: 27/04/2006, 10h20

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