Précédent   Forum des professionnels en informatique > Bases de données > Langage SQL
Langage SQL Forum d'entraide sur le langage SQL et sur les questions liées à la conception de schéma (DDL). Cours SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 14/01/2011, 15h06   #1
Invité de passage
 
Inscription : mai 2009
Messages : 13
Détails du profil
Informations forums :
Inscription : mai 2009
Messages : 13
Points : 3
Points : 3
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 :
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 :
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 :
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 :
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 :
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)
kevinh44fr est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/01/2011, 15h19   #2
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
Citation:
Envoyé par kevinh44fr Voir le message
Or moi je voudrai :

Code :
1
2
3
4
5
 
Id IdReseau IdLabel
1  1           11
1  2           12
1  NULL        13
pourquoi ca plus que

Code :
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
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/01/2011, 15h29   #3
Invité de passage
 
Inscription : mai 2009
Messages : 13
Détails du profil
Informations forums :
Inscription : mai 2009
Messages : 13
Points : 3
Points : 3
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 :
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.
kevinh44fr est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/01/2011, 15h33   #4
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
OK

Mais alors, comment choisissez vous le label a afficher pour une couple producteur/réseau donné ? (cf ma première question)
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/01/2011, 15h44   #5
Invité de passage
 
Inscription : mai 2009
Messages : 13
Détails du profil
Informations forums :
Inscription : mai 2009
Messages : 13
Points : 3
Points : 3
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 :
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 :
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
kevinh44fr est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/01/2011, 17h58   #6
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
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 !
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/01/2011, 20h58   #7
Invité de passage
 
Inscription : mai 2009
Messages : 13
Détails du profil
Informations forums :
Inscription : mai 2009
Messages : 13
Points : 3
Points : 3
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.
kevinh44fr est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/01/2011, 09h21   #8
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 10 986
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
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 : 10 986
Points : 18 234
Points : 18 234
Envoyer un message via MSN à CinePhil
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 :
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 de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« 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 Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/01/2011, 16h50   #9
Invité de passage
 
Inscription : mai 2009
Messages : 13
Détails du profil
Informations forums :
Inscription : mai 2009
Messages : 13
Points : 3
Points : 3
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.
kevinh44fr est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/01/2011, 17h17   #10
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
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 :
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 ?
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 00h47.


 
 
 
 
Partenaires

Hébergement Web