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 :

Doublons sur le résultat lors d'une jointure de 3 tables


Sujet :

Langage SQL

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 13
    Points : 6
    Points
    6
    Par défaut Doublons sur le résultat lors d'une jointure de 3 tables
    Bonjour,

    J'ai un problème de résultat en double lors de l'exécution de ma requête SQL.
    En fait, j'ai 3 tables :
    Producteur, Reseau et Label
    Un producteur peut avoir plusieurs réseaux et plusieurs labels.
    Donc, j'ai créer 2 tables d'associations pour les relier :
    Procteur_Reseau et Producteur_Label.

    Avec 1 seule requête SQL, je souhaiterai afficher les informations de chaque producteur ainsi que ses réseaux et labels.
    Mes tables sont composés comme suit :
    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
     
    Producteur
    __________
    Id
    Nom
     
    -----------------
     
    Reseau
    __________
    Id
    Nom
     
    -----------------
     
    Label
    __________
    Id
    Nom
     
    --------------------
     
    Producteur_Reseau
    __________
    Id_Producteur
    id_Reseau
     
    --------------------
     
    Producteur_Label
    __________
    Id_Producteur
    Id_Label
    Ma requête SQL :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT p.id, p.prenom, p.nom, r.id as idreseau, r.titre as reseau, l.id as idlabel, l.nom as label
    FROM producteur p JOIN producteur_reseau pr ON p.id = pr.id_producteur
                      JOIN reseau r ON pr.id_reseau = r.id
                      JOIN producteur_label pl ON p.id = pl.id_producteur
                      JOIN label l ON pl.id_label = l.id
    ORDER BY p.id;
    Imaginons que dans mes tables d'association soit remplis comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    Producteur_Reseau
    __________
    1 1
    1 2
     
    --------------------
     
    Producteur_Label
    __________
    1 11
    1 12
    1 13
    Je vais avoir comme résultat :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Id IdReseau IdLabel
    1  1           11
    1  1           12
    1  1           13
    1  2           11
    1  2           12
    1  2           13
    Or moi je voudrai :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Id IdReseau IdLabel
    1  1           11
    1  2           12
    1  null        13
    Merci de votre aide car là je ne sais vraiment pas quoi faire et je n'arrive pas à trouver de réponse sur le net (faut dire aussi que je ne sais pas vraiment avec quels termes faire la recherche)

  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
    Points : 13 092
    Points
    13 092
    Par défaut
    Citation Envoyé par kevinh44fr Voir le message
    Or moi je voudrai :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Id IdReseau IdLabel
    1  1           11
    1  2           12
    1  null        13
    pourquoi ca plus que

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Id IdReseau IdLabel
    1  1           12
    1  2           11
    1  null        13
    Qu'est-ce qui relie vos labels à vos réseau ?
    Si vos producteurs ont un label pour un reseau donné, alors vous ne devriez pas avoir une table Producteur_reseau et une table producteur_label, mais une seule table :
    producteur_reseau_label, qui contiendrait... le résultat que vous cherchez a obtenir !

    Donnez un peu plus de détails sur la logique de vos données, et ce qu'elles représentent, car la... il y a quelque chose qui cloche...

    Tel que vous présentez les choses, ce que vous voulez faire n'est pas possible, car incohérent avec votre modèle de données

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 13
    Points : 6
    Points
    6
    Par défaut
    L'ordre a peu d'importance.
    Ce que je ne veux pas, ce sont des résultats en double.

    Non, les réseaux et les labels sont des choses distinctes.
    Un producteur a des réseaux et des labels.
    Ils sont indépendants entre eux.
    C'est pour ça que j'utilise une table d'association à chaque fois.

    En fait, il faut que je liste les producteurs avec leurs caractéristiques dans un tableau (au format HTML).
    Un producteur a des réseaux et des labels.
    Je suis obligé de passer par une seule requête pour créer cette liste, donc j'utilise plusieurs jointures pour afficher les réseaux et les labels que chaque producteur possède.

    Le problème, c'est que 1 producteur peut avoir 4 réseaux et 10 labels.
    Avec ma requête, ça me fait résultat cartésien de 4 * 10 = 40 lignes.
    Or, je n'en voudrais que 10.
    Pour avoir :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    idProducteur     idReseau      idLabel
    __________      _______      ______
    1                Reseau1    Label1
    1                Reseau2    Label2
    1                Reseau3    Label3
    1                Reseau4    Label4
    1                NULL         Label5
    1                NULL         Label6
    1                NULL         Label7
    1                NULL         Label8
    1                NULL         Label9
    1                NULL         Label10
    Je ne sais pas trop quoi dire de plus.
    Je ne sais pas vraiment comment exprimer mon problème (pour ça aussi que je ne sais pas vraiment quoi rechercher sur le net).

    Mais il n'y a pas de lien entre réseaux et labels.
    Seulement entre producteur et réseaux et entre producteur et labels.
    Moi, je voudrais tout regrouper en une seule fois.

  4. #4
    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
    Points : 13 092
    Points
    13 092
    Par défaut
    OK

    Mais alors, comment choisissez vous le label a afficher pour une couple producteur/réseau donné ? (cf ma première question)

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 13
    Points : 6
    Points
    6
    Par défaut
    Euh..
    Je pense que ma requête doit être vraiment nul si tu me demandes ça.
    (et tu peux me tutoyer, j'ai que 20 ans et simple stagiaire dans l'administration publique)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    FROM producteur p JOIN producteur_reseau pr ON p.id = pr.id_producteur
                      JOIN reseau r ON pr.id_reseau = r.id
                      JOIN producteur_label pl ON p.id = pl.id_producteur
                      JOIN label l ON pl.id_label = l.id
    Je fais plusieurs JOIN. Mais je les fait peut-être mal.
    Je veux faire un JOIN sur producteur avec reseau et sur producteur avec label.
    Pas en fonction de Reseau, Label et Reseau doivent agir indépendamment.
    Donc je récupère tous les id labels correspondant dans la table producteur_label à l'id producteur.
    Pareil pour réseau.

    En gros je veux faire ces 2 requêtes mais en 1 seule fois :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SELECT p.id, r.id as idreseau, r.titre as reseau
    FROM producteur p LEFT JOIN producteur_reseau pr ON p.id = pr.id_producteur
                              LEFT JOIN reseau r ON pr.id_reseau = r.id
     
     
    SELECT p.id, l.id as idlabel, l.nom as label
    FROM producteur p LEFT JOIN producteur_label pl ON p.id = pl.id_producteur
                              LEFT JOIN label l ON pl.id_label = l.id

  6. #6
    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
    Points : 13 092
    Points
    13 092
    Par défaut
    re,

    Ce que vous voulez faire est contraire au principe même des bases de données relationnelles

    vous essayez de mettre sur la même ligne des éléments qui n'ont rien à voir entre eux : les réseaux et les labels. C'est pour cela que :
    1/ vous ne trouvez pas de solution sur le net
    2/ vous n'arrivez pas a formuler votre recherche (cela n'a pas de sens, donc comment expliquer quelque chose qui n'a pas de sens ?)
    3/vous n'y arrivez pas

    Au pire dans votre cas, si vraiment vous y tenez, vous pourriez faire un UNION entre vos deux requêtes, en ajoutant une troisième colonne type (label|réseau), mais cela n'a aucun intérêt !

    Pourquoi voulez vous effectuer vos deux requêtes en une seule fois ?
    C'est bien en deux fois qu'il faut les exécuter dans votre cas !

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 13
    Points : 6
    Points
    6
    Par défaut
    Je le sais bien, et j'aurai bien voulu faire en 2 fois.
    Seulement, je développe en Java J2EE 1.4.2 avec un framework vieux de 2004 voir 2000 (je suis stagiaire, pas le choix).
    Le framework étant trop limité, j'ai crée mon propre script de connexion à la base de donnée pour faire comme je le souhaitais et correctement.
    Seulement, ça ne leur va pas car ils veulent que j"utilise leur framework.

    Le problème, c'est qu'avec celui-là, je ne peux pas récupérer l'identifiant du producteur et relancer une requête.
    Je dois lancer des requêtes pour mes bases de données entre les chargements des pages, je ne peux pas le faire à l'intérieur de ma page jsp, le framework ne le permet pas.

    Moi je veux crée une page liste.jsp qui va lister dans un tableau HTML tous les producteurs. Mais dans ma page, je ne peux pas lancer une requête sql.
    Donc, je suis obligé de tout faire en une seule fois.

    J'ai créer un petit algorithme en attendant qui mets dans une liste mes réseaux et mes labels pour voir s'ils n'ont pas déjà été affichés, mais c'est pas très propre. Je ne voudrai pas que ça devienne une solution permanente, mais avec les moyens que j'ai, et si je ne peux pas faire autrement en ne faisant qu'une requête, alors je ne vois pas quoi faire.

  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 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    La solution logique est de faire une UNION entre les deux requêtes qui donnent, l'une les labels des producteurs, l'autre les réseaux des producteurs.
    Si un producteur à 4 labels et 10 réseaux, ça fera 14 lignes de résultat.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT p.id, r.id AS idreseau, r.titre AS reseau, NULL AS idlabel, NULL AS label
    FROM producteur p 
    LEFT JOIN producteur_reseau pr ON p.id = pr.id_producteur
      LEFT JOIN reseau r ON pr.id_reseau = r.id
    UNION
    SELECT p.id, NULL AS idreseau, NULL AS reseau, l.id AS idlabel, l.nom AS label
    FROM producteur p 
    LEFT JOIN producteur_label pl ON p.id = pl.id_producteur
      LEFT JOIN label l ON pl.id_label = l.id
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 13
    Points : 6
    Points
    6
    Par défaut
    Ce n'est pas la solution idéale que je recherchais, mais si ce n'est pas possible de faire mieux, je ferai avec.
    Merci de votre aide.

  10. #10
    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
    Points : 13 092
    Points
    13 092
    Par défaut
    Si par solution idéale, tu entends "idéale pour le développeur quitte a faire pleurer le serveur de BDD", tu as peut être une alternative : en essayant quelque chose comme ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    SELECT COALESCE(A.id, B.id), A.id AS idreseau, A.titre AS reseau, B.id AS idlabel, B.nom AS label 
    FROM
      (
       SELECT p.id, r.id AS idreseau, r.titre AS reseau, ROW_NUMBER() OVER (ORDER BY p.id) AS rn
       FROM producteur p LEFT JOIN producteur_reseau pr ON p.id = pr.id_producteur
                               LEFT JOIN reseau r ON pr.id_reseau = r.id
      ) A 
    FULL OUTER JOIN
      (                          
       SELECT p.id, l.id AS idlabel, l.nom AS label, ROW_NUMBER() OVER (ORDER BY p.id) AS rn
       FROM producteur p LEFT JOIN producteur_label pl ON p.id = pl.id_producteur
                               LEFT JOIN label l ON pl.id_label = l.id
     )B 
    ON A.id = B.id  AND A.rn = B.rn
    Je pense (pas testé) que ce devrait te donner ce que tu voulais au départ... Mais je persiste a dire que c'est une mauvaise idée... De plus ca ne fonctionnera pas sous tous les SGBDR. Quel est le tien ?

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

Discussions similaires

  1. Jointure avec plusieurs tables referentielles : erreur dsx
    Par sadounarezki dans le forum QlikView
    Réponses: 0
    Dernier message: 04/07/2015, 15h30
  2. Cast sur une clé primaire lors d'une jointure
    Par totoranky dans le forum Hibernate
    Réponses: 4
    Dernier message: 08/03/2011, 12h13
  3. Obtenir un COUNT() = 0 lors d'une jointure ?
    Par elvex dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 03/07/2007, 21h48
  4. Utiliser un tableau de résultat pour faire une jointure
    Par Xavier1979 dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 13/06/2007, 13h27
  5. [MySQL] Appliquer une fonction sur un champ lors d'une requête
    Par Jérémy197 dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 13/08/2006, 13h29

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