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 :

[SQL] Problème avec jointure externe


Sujet :

Langage SQL

  1. #1
    Membre du Club
    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 113
    Points : 65
    Points
    65
    Par défaut [SQL] Problème avec jointure externe
    Bonjour,

    Voila je suis bloqué sur un petit problème tout bébéte, mais ne n'arrive pas à m'en sortir malgrès avoir écumé les forums et sites sur SQL.
    Pour info je fais mes requêtes sous SQL Server.

    Je joue sur 4 petites tables:

    FIGURE
    ID|NAME
    1 |FIGURE1
    2 |FIGURE2
    3 |FIGURE3
    4 |FIGURE4
    5 |FIGURE5

    CATEGORY_TYPE
    ID|TYPE
    1 |COULEUR
    2 |FORME


    CATEGORY
    ID|VALUE|CATEGORY_TYPE_ID
    1 |ROND |2
    2 |CARRE|2
    3 |VERT |1
    4 |ROUGE|1
    5 |JAUNE |1

    ou CATEGORY_TYPE_ID est une FK vers CATEGORY_TYPE/ID

    FORME_COLLECTION
    ID_CATEGORY|ID_FIGURE
    1|1
    3|1
    4|2
    2|3
    5|3
    3|4
    1|5
    4|5

    ou ID_CATEGORY est une FK vers CATEGORY/ID
    et ID_FIGURE est une FK vers FIGURE/ID

    En sachant qu'une figure ne couvre pas forcement toute les category_type, c'est à dire comme les figures 2 et 4 qui n'ont pas d'affectation à une forme dans FORME_COLLECTION.

    Mon besoin étant de récuperer TOUTE la liste des figures, avec la forme associé, même si la figure n'en posséde pas.

    En gros j'aimerais récupérer:
    FIGNAME|FORMNAME
    FIGURE1|ROND
    FIGURE2|NULL
    FIGURE3|CARRE
    FIGURE4|NULL
    FIGURE5|ROND

    Seulement je n'arrive pas à effectuer une jointure externe qui me ramène tout de même les figures ne possédant pas de forme.

    Voici ma requête:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    SELECT 
    distinct 
    T1.NAME AS FIGNAME,
    T13.VALUE AS FORMNAME
    FROM 
    FIGURE T1 LEFT OUTER JOIN FORME_COLLECTION T2 ON T1.ID = T2.ID_FIGURE,
    CATEGORY T3,
    CATEGORY_TYPE T4
    WHERE 
    T2.ID_CATEGORY = T3.ID
    AND T3.CATEGORY_TYPE_ID = T4.ID
    AND T4.TYPE = 'FORME'
    Cette requête me retourne uniquement les figure possédant une forme:

    FIGNAME|FORMNAME
    FIGURE1|ROND
    FIGURE3|CARRE
    FIGURE5|ROND

    Pourriez-vous m'aider? J'ai trituré ma jointure dans tous les sens mais rien n'y fait.

    Merci beaucoup.

    Cordialement,

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 772
    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 772
    Points : 52 737
    Points
    52 737
    Billets dans le blog
    5
    Par défaut
    Il vous faire faire un produit cartésien (CROSS JOIN) et pour chaque intersection récupérer la valeur qui va bien pas une sous requête corrélée.

    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/ * * * * *

  3. #3
    Membre du Club
    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 113
    Points : 65
    Points
    65
    Par défaut
    Merci pour votre réponse, j'avais bien pensé au produit cartésien, mais je ne savais pas comment le goupiller aprés. J'avoue que je n'ai pas compris la seconde partie de votre phrase. "et pour chaque intersection récupérer la valeur qui va bien pas une sous requête corrélée."

    Cependant j'ai reussi à obtenir le résultat attendu avec cette requête:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SELECT DISTINCT 
       T1.NAME AS FIGNAME,
       T13.VALUE AS FORMNAME
    FROM CATEGORY_TYPE T4 
    INNER JOIN CATEGORY T3 ON T3.CATEGORY_TYPE_ID = T4.ID AND T4.TYPE = 'FORME' 
    LEFT outer join FORME_COLLECTION T2 ON T2.ID_CATEGORY = T3.ID RIGHT outer join,
    FIGURE T1 ON T1.ID = T2.ID_FIGURE
    J'obtient bien le résultat:
    FIGURE1|ROND
    FIGURE2|NULL
    FIGURE3|CARRE
    FIGURE4|NULL
    FIGURE5|ROND

    Suis-je dans l'erreur?

    Merci
    cordialement,

  4. #4
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 772
    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 772
    Points : 52 737
    Points
    52 737
    Billets dans le blog
    5
    Par défaut
    Quelque chose comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT NAME, TYPE, VALUE, (SELECT NAME 
                               FROM   FIGURE AS FIG
                                      INNER JOIN CATEGORY AS C
                                            ON FIG.ID =  
                               WHERE  ???)
    FROM   FIGURE AS FIG
           CROSS JOIN (SELECT TYPE, VALUE 
                       FROM   CATEGORY AS CTG
                              INNER JOIN CATEGORY_TYPE AS CTT
                                    ON CTG.ID = CTT.CATEGORY_TYPE_ID) AS CRS
    mais il ne m'est pas possible de continuer car vous avez stupidement nommé toutes vos clef ID ce qui rend votre base incompréhensible !

    Un règle d'or d'un modèle de données, qui est d'ailleurs une norme AFNOR impose qu'une même information ait toujours le même nom dans un système d'information. Or vous avez mis partout ID !!!!!
    Si vous avez conçu un CMD cette faute vous aurait sauté aux yeux...

    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/ * * * * *

  5. #5
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Voici une requête :
    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
    With FIGURE (ID, NAME) AS
    (
    select 1, 'FIGURE1' union all
    select 2, 'FIGURE2' union all
    select 3, 'FIGURE3' union all
    select 4, 'FIGURE4' union all
    select 5, 'FIGURE5'
    )
      ,  CATEGORY_TYPE (ID, TYPE) AS
    (
    select 1, 'COULEUR' union all
    select 2, 'FORME'
    )
      ,  CATEGORY (ID, VALUE, CATEGORY_TYPE_ID) AS
    (
    select 1, 'ROND' , 2 union all
    select 2, 'CARRE', 2 union all
    select 3, 'VERT' , 1 union all
    select 4, 'ROUGE', 1 union all
    select 5, 'JAUNE', 1
    )
      ,  FORME_COLLECTION (ID_CATEGORY, ID_FIGURE) AS
    (
    select 1, 1 union all
    select 3, 1 union all
    select 4, 2 union all
    select 2, 3 union all
    select 5, 3 union all
    select 3, 4 union all
    select 1, 5 union all
    select 4, 5
    )
    SELECT
        FG.NAME  AS FIGNAME,
        CG.VALUE AS FORMNAME
    FROM
        FIGURE AS FG
        LEFT OUTER JOIN FORME_COLLECTION AS FC
        INNER JOIN CATEGORY AS CG
          ON CG.ID = FC.ID_CATEGORY
        INNER JOIN CATEGORY_TYPE AS CT
          ON CT.ID = CG.CATEGORY_TYPE_ID
         AND CT.TYPE = 'FORME'
          ON FC.ID_FIGURE = FG.ID;
     
    FIGNAME FORMNAME
    ------- --------
    FIGURE1 ROND
    FIGURE2 NULL
    FIGURE3 CARRE
    FIGURE4 NULL
    FIGURE5 ROND
    Dans cette syntaxe, vous constaterez que le prédicat de jointure externe n'arrive qu'en dernier, c'est pour faire les jointures fortes entre les autres tables en premier et seulement après la jointure externe sur le résultat.

    Mefiez-vous du sens des jointures externes, c'est facile de s'y perdre je vous invite à les mettre toujours dans le même sens : évitez si vous le pouvez d'avoir des left et des right dans la même requête.

    Le distinct, comme vous le constatez, n'est pas utile.

Discussions similaires

  1. Optimisation requête avec jointure externe SQL Server
    Par ICEMAN_60 dans le forum Développement
    Réponses: 2
    Dernier message: 28/11/2011, 10h08
  2. Problème avec jointure externe
    Par ouinih dans le forum PL/SQL
    Réponses: 6
    Dernier message: 27/07/2011, 11h20
  3. Réponses: 5
    Dernier message: 30/03/2009, 10h04
  4. Problème avec jointure externe
    Par illight dans le forum Langage SQL
    Réponses: 1
    Dernier message: 09/04/2008, 12h23
  5. [SQL]Problème avec jointure de tables
    Par benjisan dans le forum Requêtes et SQL.
    Réponses: 16
    Dernier message: 29/03/2007, 20h43

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