[mysql]requête jointure sur 3 tables et une clé de liaison [Résolu]

Messages postés
19
Date d'inscription
mercredi 20 août 2003
Statut
Membre
Dernière intervention
14 juillet 2006
- - Dernière réponse : Sedilbur
Messages postés
19
Date d'inscription
mercredi 20 août 2003
Statut
Membre
Dernière intervention
14 juillet 2006
- 12 juil. 2006 à 22:02
Bonjour à tous,
Je viens aujourd'hui à vous pour vous demander de l'aide car je bloque au niveau d'une rêquete SQL.

Je vous expose la situation pour mieux vous expliquer mon problème

J'ai 3 TABLES: (je vous épargne les types etc... et je vais à l'essentiel)
<li>table1 stats1> 3 champs ('rank', 'point', 'player')</li><li>table2 =stat2 => 3 champs ('rank', 'point', 'player')</li><li>table3 = stat3 => 3 champs ('rank', 'point', 'player')</li>La jointure doit être faite sur le champ player. les champs rank et point des 3 tables sont bien entendu différentes...

Ce que je veux:
Il faut qu'en une requête, je puisse récupérer le contenu des champs rank et point de chacunes des 3 tables grâce à la clée player. Alors déjà, je sais que je peux faire ça avec 3 requêtes différentes, mais c'est justement ce que je veux éviter. Il faut dire que j'ai toujours opté pour cette solution dans le passée...c'est pourquoi, aujourd'hui j'aimerais changer mes habitudes  si bien entendu, ce que je demande est possible (mais je pense bien que oui :p)

Les cas possibles:
<ol><li>Un joueur peut se retrouver dans les 3 tables, comme il pourrait se retrouver dans aucunes des 3 tables.</li><li>Un joueur peut se retrouver sur  1, voir 2 tables en même temps.
</li></ol>Voilà, je pense que c'est clair...celà dit, si vous assez des questions n'hésitez pas à me les poser. Il serait bien également que vous expliquiez un peu votre requête...(histoire que je copie pas bêtement quoi )

Mon problème:
Mon problème est simple, je n'arrive pas à réunir les 2 cas...en effet, après de multiples tests: je n'arrive à récupérer les contenus voulus que si et seulement si, le joueur se retrouve dans chacunes des 3 tables.

Voilà à quoi je suis arrivé:

SELECT f.rank as rank_fleet, f.points as points_fleet, p.rank as rank_points, p.points as points_pointq, r.rank as rank_research, r.points as points_research
    FROM stat1 as f, stat2 as p, stat3 as r
    WHERE f.player = 'test'

Bon je sais très bien qu'avec cette requête je suis complètement à l'Ouest mais au moins, j'ai essayé et je dois dire que je n'ai jamais été doué pour ça (d'où mon penchant pour la solution plusieurs requêtes )...
Afficher la suite 

20/21 réponses

Meilleure réponse
Messages postés
10918
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
17
3
Merci
Tu ne peux pas faire un coalesce sur le résultat d'un select renvoyant plusieurs champs. coalesce ne se fait que sur UNE valeur.
Idem pour le AS. TU ne peux pas stocker 2 résultats comme ça.
Tu dois faire autant de select, dans ce cas-ci, que tu as de champs.

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 122 internautes nous ont dit merci ce mois-ci

Commenter la réponse de malalam
Messages postés
91
Date d'inscription
mercredi 26 janvier 2005
Statut
Membre
Dernière intervention
16 septembre 2010
0
Merci
salut,

ta requête ne me parait pas fausse à première vue, il faudrait juste que tu fasses des jointures entre tes tables, du style:
and f.joueur=p.joueur
and f.joueur=r.joueur;

J'attends que tu me dises si ça te va ou pas

Tchao

 
Commenter la réponse de 3xodius55
Messages postés
154
Date d'inscription
samedi 25 octobre 2003
Statut
Membre
Dernière intervention
5 septembre 2008
0
Merci
Slt

T n'as pas de 'AS' au niveau du from pour renommer tes tables.
Voici la solution, regarde si elle te conviens peut etre que tu as besoin de jointure comme te la montré la personne précédente.

Si tu souhaite renommer tes champs tu peux remettre ta syntaxe

Select S1.rank,S1.point,S1.player,S2.rank,S2.point,S2.player,S3.rank,S3.point,S3.player
From stats1 S1 ,stats2 S2 ,stats3 S3
Where f.player = 'test';
Commenter la réponse de Paladin2107
Messages postés
91
Date d'inscription
mercredi 26 janvier 2005
Statut
Membre
Dernière intervention
16 septembre 2010
0
Merci
Ah bon, il ne faut pas de AS ?

J'étais persuadé qu'il était optionnel mais pas faux...

On en apprend tous les jours !

 
Commenter la réponse de 3xodius55
Messages postés
19
Date d'inscription
mercredi 20 août 2003
Statut
Membre
Dernière intervention
14 juillet 2006
0
Merci
Très bien je vais tester celà le plus vite possible et je vous tiens au courant...
Commenter la réponse de Sedilbur
Messages postés
10918
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
17
0
Merci
Hello,

SELECT
f.rank as rank_fleet, f.points as points_fleet, p.rank as rank_points, p.points as points_pointq, r.rank as rank_research, r.points as points_research 
FROM stat1 as f, stat2 as p, stat3 as r
WHERE
f.player = 'test' AND
f.player = p.player AND
p.player = r.player
Commenter la réponse de malalam
Messages postés
19
Date d'inscription
mercredi 20 août 2003
Statut
Membre
Dernière intervention
14 juillet 2006
0
Merci
Voilà j'ai fais des tests...des différentes requêtes que vous avez proposé et donc...

Select S1.rank,S1.point,S1.player,S2.rank,S2.point,S2.player,S3.rank,S3.point,S3.player
From stats1 S1 ,stats2 S2 ,stats3 S3
Where f.player = 'test';

Le problème est que cette requête me retourne les différentes stats seulement si le joueur est dans les 3 tables...si jamais il est seulement dans une seule, la requête me retourne rien

WHERE f.player = 'test' AND
f.player = p.player AND
p.player = r.player

Même problème, la requête me retourne bien les statistiques du joueurs mais seulement si ce dernier est dans les 3 tables.

J'avais essayé celà mais encore une fois ça m'a pas fonctionné

WHERE f.player = 'test' or
f.player = 'test' or
p.player = 'test'

Le problème est qu'il récupère bien les stats du joueur si celui-ci est dans une seule table mais il prend également celui d'un autre.
exemple:
test est dans les 3 tables
moi est dans une seule table

La requête me renvoie les résultats de moi de la table ou il est + les résultats de test dans les deux autres tables

Voilà, j'espère que vous pourez m'aider parce que là, je commence un petit peu à désespérer...

...
Commenter la réponse de Sedilbur
Messages postés
10918
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
17
0
Merci
Tu as quelle version de mysql ?
Commenter la réponse de malalam
Messages postés
10918
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
17
0
Merci
Parce que j'avais mal lu ton bin's. Bref essaye :

SELECTrank, point, player
FROM stats1
NATURALLEFTJOIN stats2
NATURALLEFTJOIN stats3
WHERE player ='test'
Commenter la réponse de malalam
Messages postés
154
Date d'inscription
samedi 25 octobre 2003
Statut
Membre
Dernière intervention
5 septembre 2008
0
Merci
SELECT rank, point, player
FROM stats1
UNION
SELECT rank, point, player
FROM stats2
UNION
SELECT rank, point, player
FROM stats3
Commenter la réponse de Paladin2107
Messages postés
2368
Date d'inscription
mercredi 13 octobre 2004
Statut
Membre
Dernière intervention
18 avril 2015
3
0
Merci
le Union est quelque chose d'assez horrible.

La jointure externe est obligatoire ici. J'irais plus dans le sens de Malalam.
Te reste à ajouter les ON table1.id = table2.id et normalement ca doit passer :)
Commenter la réponse de FhX
Messages postés
19
Date d'inscription
mercredi 20 août 2003
Statut
Membre
Dernière intervention
14 juillet 2006
0
Merci
Bonsoir à tous,

Bon j'ai bien lu vos messages, et j'ai essayé au plus vite vos solutions mais malheureusement sans succès...

Alors je tiens à préciser une chose, ma requête ne doit pas récupérer les stats de tous les joueurs à la fois, mais seulement d'un seul. (c'est pour une signature dynamique)

malalam->Ta requête me renvoie uniquement les valeurs qui sont dans la table du from (ici stat1) et ignore complètement ceux des deux autres tables...

Je vais donc essayer de mieux expliquer mon problème avec un exemple concret (ce sera surement plus simple à expliquer):

Soit 3 tables:

1) Table_fleet qui contient les champs suivants:
player
rank
points

2) Table_points qui contient les champs suivants:

player

rank

points

3) Table_research qui contient les champs suivants:

player

rank

points

Maintenant, prenons un exemple de contenu possible (de ces 3 tables)

Contenu table_fleet:
Test----------500--------------500000
Moi-----------400--------------700000

Contenu table_points:
Test-----------200-------------136
Test2-----------1000----------80
Contenu table_research:
Test-----------300-------------1000000
Moi-------------800-------------800000

Il me faut une rêquete qui me permette de récupera les stats d'un joueur donné

Prenons par exemple pour le joueur Moi:
La requête doit me revoyer:
de la table_fleet
rank->400
points->700000

de la table_research
rank->800
points->800000

De même pour le joueur Test:
la requête doit me renvoyer:
de la table_fleet

rank->500

points->500000


de la table_points
rank->200

points->136


de la table_research
rank->300


points->1000000


Donc voilà, j'espère que cette explication sera plus claire et moins ambigue que la premiere...

Je vous remercie également pour votre attention, et votre aide sans laquelle, je serais sûrement retourné a mes méthodes bourines :p
Commenter la réponse de Sedilbur
Messages postés
19
Date d'inscription
mercredi 20 août 2003
Statut
Membre
Dernière intervention
14 juillet 2006
0
Merci
J'oubliais, j'utilise cette version de mysql->5.0.22-community-nt

...
Commenter la réponse de Sedilbur
Messages postés
10918
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
17
0
Merci
Hello,

alors ça c'est très bizarre, parce que j'utilise une version de mysql similaire à la tienne, et que ma requête marchait.
mais bon, merci pour les exemples, je vais créer la même table que toi et on verra bien...! On trouvera :-) En tous cas, problème SQL intéressant (tu devrais peut-être aussi poser ta question sur le forum SQL, d'ailleurs).
Commenter la réponse de malalam
Messages postés
10918
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
17
0
Merci
Et j'y pense, mais si puisque tu utilises une version 5 de mysql, il y a un truc certes très peu élégant, mais qui marchera probablement : la technique des 3 requêtes en une ;-) Mais il faudrait quand même chercher avec les jointures...
Essaye quand même:

SELECT
COALESCE((SELECT champ1, champ2 FROM table1 WHERE champ3='bla'), 'n/a') AS resultat1,
COALESCE((SELECT champ1, champ2 FROM table2 WHERE champ3='bla'), 'n/a') AS resultat2,
COALESCE((SELECT champ1, champ2 FROM table3 WHERE champ3='bla'), 'n/a) AS resultat3
Commenter la réponse de malalam
Messages postés
10918
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
17
0
Merci
en jouant éventuellement avec NULLIF, et des CASE...pour être sûr.
Commenter la réponse de malalam
Messages postés
10918
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
17
0
Merci
et j'ai oublié une apostrophe après le dernier n/a.
Commenter la réponse de malalam
Messages postés
19
Date d'inscription
mercredi 20 août 2003
Statut
Membre
Dernière intervention
14 juillet 2006
0
Merci
Désolé du retard...alors la rêquete trois en une (si je puis dire lol) ne fonctionne pas...en tout cas, MYSQL me renvoie une erreur...

SELECT
  COALESCE((SELECT rank as rank_fleet, points as points_fleet FROM ogspy_tshauniver14rank_fleet WHERE player='test'), 'n/a') AS resultat1,
  COALESCE((SELECT rank as rank_points, points as points_points FROM ogspy_tshauniver14rank_points WHERE player='test'), 'n/a') AS resultat2,
  COALESCE((SELECT rank as rank_research, points as points_research FROM ogspy_tshauniver14rank_research WHERE player='test'), 'n/a') AS resultat3

l'erreur:
#1241 - Operand should contain 1 column(s)

Il faut dire que c'est la première fois que j'utilise ce genre de requête et donc, étant néophyte dans ce domaine, il se pourrait que je me trompe dans l'utilisation de la rêquete...m'enfin, même si dans ce cas, j'ai retourné la requête dans tous les sens, et j'ai toujours la même erreur :p

Mais je pense que tu as compris ce que je voulais...c'est déjà un bon pas pour ma part. En effet, en temps normal, j'aurais dû faire ces 3 requêtes pour avoir le résultat escompté (EF: mon exemple) mais comme je veux une methode plus propre, je désire une "requête magique" qui me permette d'avoir le même résultat avec une seule requête.

Mais je dois dire que je bloque, et re-bloque et c'est très agacant (enfin comme tout ce qu'on arrive pas à faire lol)

Je vais encore essayé de potasser le manual mysql. Et je vais également aller poster cette demande dans le forum SQL le plus vite possible.

Merci de ton aide en espérant que l'on trouve une solution tout de même :p

Commenter la réponse de Sedilbur
Messages postés
19
Date d'inscription
mercredi 20 août 2003
Statut
Membre
Dernière intervention
14 juillet 2006
0
Merci
Merci pour ces précisions malalam...Alors effectivement, avec cette méthode, j'obtiens bien ce que je veux (voir exemple au dessus)

Là voici:
$sql = "SELECT
  COALESCE((SELECT rank FROM ogspy_tshauniver14rank_fleet WHERE player='". $player ."'), 'n/a') AS rank_fleet,
  COALESCE((SELECT points FROM ogspy_tshauniver14rank_fleet WHERE player='". $player ."'), 'n/a') AS points_fleet,
  COALESCE((SELECT rank FROM ogspy_tshauniver14rank_points WHERE player='". $player ."'), 'n/a') AS rank_points,
  COALESCE((SELECT points FROM ogspy_tshauniver14rank_points WHERE player='". $player ."'), 'n/a') AS points_points,
  COALESCE((SELECT rank FROM ogspy_tshauniver14rank_research WHERE player='". $player ."'), 'n/a') AS rank_research,
  COALESCE((SELECT points FROM ogspy_tshauniver14rank_research WHERE player='". $player ."'), 'n/a') AS points_research";

Maintenant, il ne reste plus d'a la transformer en une requête moins barbare :p mais je dois dire que je bloque toujours, et donc si jamais vous avez des idées, n'hésitez surtout pas.

...
Commenter la réponse de Sedilbur
Messages postés
10918
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
17
0
Merci
au passage, je viens de voir que la mauvaise syntaxe (coalesce sur plusieurs champs) vient de moi, lol, désolé!
Je regarderai pour transformer ça en une requête plus sympa.
Commenter la réponse de malalam