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 :

Supprimer le produit cartésien d'une jointure


Sujet :

Langage SQL

  1. #1
    Rédacteur
    Avatar de David55
    Homme Profil pro
    Ingénieur informatique
    Inscrit en
    Août 2010
    Messages
    1 542
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Août 2010
    Messages : 1 542
    Points : 2 808
    Points
    2 808
    Par défaut Supprimer le produit cartésien d'une jointure
    * Bonjour, *

    Tout est dit dans le titre.
    Pour exemple, j'ai une requête dans laquelle je joint trois tables entre elles:

    PLAT1=>MENU1=>PLAT2

    Cependant, PLAT1 n'a pas le même nombre de ligne que PLAT2 ce qui me donne le résultat en pièce jointe!

    Comment faire pour ne plus avoir "O Taboulé 0 Céleri rémoulade" sur trois lignes mais l'avoir qu'une seul fois.

    Ma requête est assez complexe, donc je vous montre une version simplifié (je n'ai pas mis les vrais jointure car il y beaucoup plus de tables):

    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
    SELECT MENU.Menu, PlatD1, PlatD2
    FROM
    (
        SELECT DISTINCT libelle AS Menu
        FROM Menus_Principaux
    ) MENU 
        LEFT JOIN 
    (
        SELECT Menu,  PlatD1
        FROM Menus_Principaux M, Famille_Plat FP, Plat_Menu PM
        WHERE PM.jointure = M.Jointure
        AND FP.jointure = PM.jointure
        AND PM.date='2010-01-18'
        GROUP BY Menu, FP.libelle
    ) DAY1 ON MENU.Menu = DAY1.Menu
        LEFT JOIN
    (
         SELECT Menu,  PlatD1
        FROM Menus_Principaux M, Famille_Plat FP, Plat_Menu PM
        WHERE PM.jointure = M.Jointure
        AND FP.jointure = PM.jointure
        AND PM.date='2010-01-19'
        GROUP BY Menu, FP.libelle
    ) DAY2 ON MENU.Menu = DAY2.Menu
    WHERE PlatD1 IS NOT NULL
    OR PlatD2 IS NOT NULL
    * Merci *
    Images attachées Images attachées  

  2. #2
    Membre averti Avatar de LBO72
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    406
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 406
    Points : 342
    Points
    342
    Par défaut
    Ceci devrait répondre à ton besoin :

    Avant de lancer ton select, lances ce qui suit :

    .... Et tiens nous informés.

    Cdlt,
    LBO72

  3. #3
    Rédacteur
    Avatar de David55
    Homme Profil pro
    Ingénieur informatique
    Inscrit en
    Août 2010
    Messages
    1 542
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Août 2010
    Messages : 1 542
    Points : 2 808
    Points
    2 808
    Par défaut
    Break n'est pas reconnu par SQL !

    Sinon j'ai réussit ce que je voulais avoir.
    Je vous partage ma réflexion:
    Lorsque nous faisons une jointure, SQL nous fait le produit cartésien entre les deux tableaux en question.
    Si mes deux tableaux ne possède qu'une seul et unique ligne, (le produit cartésien de 1 avec 1 = 1) alors je n'ai pas de doublons! Logique!
    Donc il suffit de concaténer toutes les ligne de mon premier tableau ainsi que toutes les lignes de mon deuxième tableau, puis de faire une jointure.
    De plus, la fonction SQL qui permet de concaténé permet de séparer chaque ligne concaténé par un caractère (pourquoi pas \n qui me permet de retourner à la ligne!).

    Ce qui nous donne en version très simplifié :
    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
     
    SELECT MENU.Menu, PlatD1, PlatD2
    FROM
    (
        SELECT DISTINCT libelle AS Menu
        FROM Menus_Principaux
    ) MENU 
        LEFT JOIN 
    (   
        SELECT DAY1_NON_CONCAT.Menu AS Menu, GROUP_CONCAT(DISTINCT DAY1_NON_CONCAT.PlatD1 SEPARATOR " \n ") AS PlatD1
        FROM
        (   SELECT CMPD.libelle AS Menu, CONCAT(" O ", GROUP_CONCAT(DISTINCT PlatD1 SEPARATOR " O ")) AS PlatD1
            FROM Menus_Principaux M, Famille_Plat FP, Plat_Menu PM
            WHERE PM.jointure = M.Jointure
            AND FP.jointure = PM.jointure
            AND PM.date='2010-01-18'
            GROUP BY Menu, FP.libelle        
        ) AS DAY1_NON_CONCAT
        GROUP BY DAY1_NON_CONCAT.Menu
    ) DAY1 ON MENU.Menu = DAY1.Menu
        LEFT JOIN
    (
       SELECT DAY1_NON_CONCAT.Menu AS Menu, GROUP_CONCAT(DISTINCT DAY1_NON_CONCAT.PlatD2 SEPARATOR " \n ") AS PlatD2
        FROM
        (   SELECT CMPD.libelle AS Menu, CONCAT(" O ", GROUP_CONCAT(DISTINCT PlatD2 SEPARATOR " O ")) AS PlatD2
            FROM Menus_Principaux M, Famille_Plat FP, Plat_Menu PM
            WHERE PM.jointure = M.Jointure
            AND FP.jointure = PM.jointure
            AND PM.date='2010-01-19'
            GROUP BY Menu, FP.libelle        
        ) AS DAY1_NON_CONCAT
        GROUP BY DAY1_NON_CONCAT.Menu
    ) DAY2 ON MENU.Menu = DAY2.Menu
    WHERE PlatD1 IS NOT NULL
    OR PlatD2 IS NOT NULL

  4. #4
    Membre averti Avatar de LBO72
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    406
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 406
    Points : 342
    Points
    342
    Par défaut
    ....
    Break n'est pas reconnu par SQL !....
    Comment ça ?

  5. #5
    Rédacteur
    Avatar de David55
    Homme Profil pro
    Ingénieur informatique
    Inscrit en
    Août 2010
    Messages
    1 542
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Août 2010
    Messages : 1 542
    Points : 2 808
    Points
    2 808
    Par défaut
    J'ai essayé et il m'a indiqué une erreur sur la ligne !!!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Error Code: 1064
    You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'BREAK ON PlatD2' at line 1)
    Pour info, J'utilise MySQL Workbench.

  6. #6
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 103
    Points : 28 394
    Points
    28 394
    Par défaut
    BREAK n'est nullement une commande du langage SQL, je le confirme.

    Sans doute une commande spécifique à un interpréteur de commande propre à un SGBD...

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Novembre 2009
    Messages : 84
    Points : 80
    Points
    80
    Par défaut
    Les lignes qui apparaissent en trop ce n'est pas à cause du LEFT dans la jointure ?

  8. #8
    Rédacteur
    Avatar de David55
    Homme Profil pro
    Ingénieur informatique
    Inscrit en
    Août 2010
    Messages
    1 542
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Août 2010
    Messages : 1 542
    Points : 2 808
    Points
    2 808
    Par défaut
    Les lignes qui apparaissent en trop ce n'est pas à cause du LEFT dans la jointure ?
    Effectivement, c'est à cause du LEFT mais c'est surtout à cause de la jointure que ça soit LEFT ou non, une jointure fait un produit cartésien entre deux tableaux!

Discussions similaires

  1. Lier un produit cartésien a une table par un left join
    Par eliamat dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 17/12/2014, 14h51
  2. Question SQL Jointure - Produit cartésien ?
    Par tamise dans le forum Langage SQL
    Réponses: 4
    Dernier message: 25/01/2014, 17h49
  3. Réponses: 1
    Dernier message: 27/04/2012, 10h06
  4. Produit cartésien au lieu d'une jointure
    Par Smix007 dans le forum Débuter
    Réponses: 1
    Dernier message: 17/04/2008, 14h50
  5. Réponses: 10
    Dernier message: 12/07/2006, 13h00

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