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

Résolu
Sedilbur
Messages postés
19
Date d'inscription
mercredi 20 août 2003
Statut
Membre
Dernière intervention
14 juillet 2006
- 9 juil. 2006 à 23:15
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 )...

21 réponses

malalam
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Membre
Dernière intervention
2 mars 2010
25
12 juil. 2006 à 09:39
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.
3
3xodius55
Messages postés
91
Date d'inscription
mercredi 26 janvier 2005
Statut
Membre
Dernière intervention
16 septembre 2010

10 juil. 2006 à 08:49
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

 
0
Paladin2107
Messages postés
154
Date d'inscription
samedi 25 octobre 2003
Statut
Membre
Dernière intervention
5 septembre 2008
1
10 juil. 2006 à 09:17
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';
0
3xodius55
Messages postés
91
Date d'inscription
mercredi 26 janvier 2005
Statut
Membre
Dernière intervention
16 septembre 2010

10 juil. 2006 à 09:22
Ah bon, il ne faut pas de AS ?

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

On en apprend tous les jours !

 
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Sedilbur
Messages postés
19
Date d'inscription
mercredi 20 août 2003
Statut
Membre
Dernière intervention
14 juillet 2006

10 juil. 2006 à 10:59
Très bien je vais tester celà le plus vite possible et je vous tiens au courant...
0
malalam
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Membre
Dernière intervention
2 mars 2010
25
10 juil. 2006 à 11:52
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
0
Sedilbur
Messages postés
19
Date d'inscription
mercredi 20 août 2003
Statut
Membre
Dernière intervention
14 juillet 2006

10 juil. 2006 à 13:20
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...

...
0
malalam
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Membre
Dernière intervention
2 mars 2010
25
10 juil. 2006 à 14:00
Tu as quelle version de mysql ?
0
malalam
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Membre
Dernière intervention
2 mars 2010
25
10 juil. 2006 à 14:27
Parce que j'avais mal lu ton bin's. Bref essaye :

SELECTrank, point, player
FROM stats1
NATURALLEFTJOIN stats2
NATURALLEFTJOIN stats3
WHERE player ='test'
0
Paladin2107
Messages postés
154
Date d'inscription
samedi 25 octobre 2003
Statut
Membre
Dernière intervention
5 septembre 2008
1
10 juil. 2006 à 15:02
SELECT rank, point, player
FROM stats1
UNION
SELECT rank, point, player
FROM stats2
UNION
SELECT rank, point, player
FROM stats3
0
FhX
Messages postés
2350
Date d'inscription
mercredi 13 octobre 2004
Statut
Membre
Dernière intervention
18 avril 2015
3
10 juil. 2006 à 18:15
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 :)
0
Sedilbur
Messages postés
19
Date d'inscription
mercredi 20 août 2003
Statut
Membre
Dernière intervention
14 juillet 2006

11 juil. 2006 à 01:47
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
0
Sedilbur
Messages postés
19
Date d'inscription
mercredi 20 août 2003
Statut
Membre
Dernière intervention
14 juillet 2006

11 juil. 2006 à 01:51
J'oubliais, j'utilise cette version de mysql->5.0.22-community-nt

...
0
malalam
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Membre
Dernière intervention
2 mars 2010
25
11 juil. 2006 à 08:26
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).
0
malalam
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Membre
Dernière intervention
2 mars 2010
25
11 juil. 2006 à 08:32
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
0
malalam
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Membre
Dernière intervention
2 mars 2010
25
11 juil. 2006 à 08:32
en jouant éventuellement avec NULLIF, et des CASE...pour être sûr.
0
malalam
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Membre
Dernière intervention
2 mars 2010
25
11 juil. 2006 à 08:33
et j'ai oublié une apostrophe après le dernier n/a.
0
Sedilbur
Messages postés
19
Date d'inscription
mercredi 20 août 2003
Statut
Membre
Dernière intervention
14 juillet 2006

11 juil. 2006 à 20:21
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

0
Sedilbur
Messages postés
19
Date d'inscription
mercredi 20 août 2003
Statut
Membre
Dernière intervention
14 juillet 2006

12 juil. 2006 à 18:26
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.

...
0
malalam
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Membre
Dernière intervention
2 mars 2010
25
12 juil. 2006 à 20:23
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.
0