Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1240 connectés 

  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  [MySQL] Requete avec JOIN : infos dans des bases différentes

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[MySQL] Requete avec JOIN : infos dans des bases différentes

n°1907038
Pascal le ​nain
Posté le 21-07-2009 à 01:54:23  profilanswer
 

Bonjour,
 
J'ai une table contenant des objets ayant chacun un id.
 

space_map
 
x  y  type  id
--------------
0  5  1      6
1 17  3      9
etc...  


 
Chaque enregistrement est soit une étoile, soit une planète, soit un astéroïde selon le champs 'type' (1:etoile, 2:planete, 3:asteroide).
Avec un JOIN, je voudrais chercher l'image de l'objet. Cette image est stockée dans le champs 'map_image' de la table lui correspondant.
En effet, il y a 3 tables 'etoile', 'planete' et 'asteroide'.
 
Par exemple pour l'étoile :
 

etoile
 
id     map_image     etc...
---------------------------
 6   etoile1.png
etc...


Ces 3 tables sont complètement différentes mais ont en commun les champs id et map_image.
Donc je voudrais que selon le type de l'enregistrement, on aille chercher l'image qui correspond dans la table appropriée.
 
Ca n'a pas l'air très complexe, c'est pourquoi j'ai pensé pouvoir le faire en une seule requète, mais je suis bloqué.
Voila ce que j'ai actuellement :
 

Code :
  1. SELECT space_map.* , etoile.map_image, planete.map_image, asteroide.map_image,
  2. FROM space_map
  3. INNER  JOIN etoile ON ( space_map.type =1 AND space_map.id = etoile.id )
  4. INNER  JOIN planete ON ( space_map.type =2 AND space_map.id = planete.id )
  5. INNER  JOIN asteroide ON ( space_map.type =3 AND space_map.id = asteroide.id )
  6. WHERE space_map.x >0
  7. AND space_map.x <20
  8. AND space_map.y >0
  9. AND space_map.y <20


Mais ca ne fonctionne évidement pas, puisqu'il ne sait pas comment chercher les 2 autres map_image....
 
Existe-t-il un JOIN spécial qui répondrait à mes attentes ?
 
Merci de votre attention  :hello:


Message édité par Pascal le nain le 21-07-2009 à 01:59:14
mood
Publicité
Posté le 21-07-2009 à 01:54:23  profilanswer
 

n°1907115
Pascal le ​nain
Posté le 21-07-2009 à 10:58:06  profilanswer
 

Un ami m'a proposé ca :
 

Code :
  1. SELECT space_map.* , etoile.map_image, planete.map_image, asteroide.map_image,
  2. FROM space_map
  3. INNER  JOIN etoile ON (space_map.id = etoile.id )
  4. INNER  JOIN planete ON (space_map.id = planete.id )
  5. INNER  JOIN asteroide ON ( space_map.id = asteroide.id )
  6. WHERE space_map.x >0
  7. AND space_map.x <20
  8. AND space_map.y >0
  9. AND space_map.y <20


 
Et à ce moment là, sql nous retourne les 3 images correspondantes à l'id dans chaque type (à condition que l'id existe).
Il suffit alors de choisir l'image entre les 3 en fonction du type retourné.
 
Ce n'est pas une mauvaise idée, mais au niveau performance, il doit y avoir mieux à faire. En effet, sql me retourne 2 strings pour rien.
Or c'est une requete que je vais faire très fréquemment. Je souhaite donc l'optimiser un max.
 
Petit up  :hello:

n°1907336
tet2neu
emmerdeur
Posté le 21-07-2009 à 17:15:15  profilanswer
 

Code :
  1. SELECT
  2.   space_map.*,
  3.   coalesce(etoile.map_image,planete.map_image,asteroide.map_image) map_image
  4. FROM space_map
  5. left  JOIN etoile ON space_map.id = etoile.id
  6. left  JOIN planete ON space_map.id = planete.id
  7. left  JOIN asteroide ON pace_map.id = asteroide.id
  8. WHERE space_map.x >0
  9. AND space_map.x <20
  10. AND space_map.y <20


 
je sais pas à quoi correspond ta clause where donc je l'ai laissée

n°1907360
Pascal le ​nain
Posté le 21-07-2009 à 17:52:01  profilanswer
 

Bien essayé ;)
 
Mais coalesce retourne le premier non nul.
Or il peut très bien avoir une étoile et une planete qui ont le même id.
L'astre est identifié, non pas juste par un id, mais par son type ET son id au sein de son type :)
 
Si vraiment rien n'est faisable, je donnerai effectivement un identifiant unique à tous les astres tel qu'il n'y aura pas de collisions.
 
Pour la clause where, c'est juste un genre de champs de vision. Chaque astre est visible si on le regarde. Le champs de vision est pour l'instant un carré de 20x20. Mais ca n'influe pas sur la requete ;)

n°1907370
tet2neu
emmerdeur
Posté le 21-07-2009 à 18:09:53  profilanswer
 

et en remettant le type = X dans les jointures ?


Message édité par tet2neu le 21-07-2009 à 18:10:10
n°1907373
Pascal le ​nain
Posté le 21-07-2009 à 18:18:46  profilanswer
 

J'essaye ca ce soir ;)
 
Sinon une petite question toute autre, je cherche à récupérer la valeur de l'index (la clé primaire) d'une table. J'ai d'abord pensé à un SELECT MAX(id), mais on n'est pas à l'abri d'une suppression du dernière enregistrement. J'ai ensuite cherché du coté des fonctions php, mais aucune ne semble remplir cette fonction...

n°1907382
tet2neu
emmerdeur
Posté le 21-07-2009 à 18:49:14  profilanswer
 

c'est un auto increment ?
je crois que la fonction mysql_insert_id (ou truc comme ça) renvoie le dernier id inséré ;)

n°1907388
Pascal le ​nain
Posté le 21-07-2009 à 19:50:45  profilanswer
 

Oui il est possible d'avoir l'id à l'insertion. Mais je souhaite le récupérer n'importe quand. Bizarre que personne n'y ait pensé...  :sweat:  
Je ne vais quand même pas insérer puis supprimer juste pour avoir l'id, ce serait ridicule...

n°1907393
Pascal le ​nain
Posté le 21-07-2009 à 20:00:54  profilanswer
 

Voila j'ai testé
 

SELECT space_map.*, COALESCE(etoile.map_image, planete.map_image, asteroide.map_image)  
FROM space_map  
INNER JOIN etoile ON (space_map.type=1 AND space_map.id=etoile.id)  
INNER JOIN planete ON (space_map.type=2 AND space_map.id=planete.id)  
INNER JOIN asteroide ON (space_map.type=3 AND space_map.id=asteroide.id)


En ayant viré le WHERE.
 
Il n'y a plus d'erreur SQL, mais sql ne renvoie aucun enregistrement...
Pourtant il me semble que l'on ne filtre rien...

n°1907394
tet2neu
emmerdeur
Posté le 21-07-2009 à 20:05:43  profilanswer
 

c'est normal que ça ne renvoie rien, il faut du left join et pas du inner join ;)

 

en gros, avec le inner, tu lui demande de renvoyer tous les objets qui sont à la fois une étoile, une planète et un astéroïde. Et j'imagine que tu n'en as pas :)


Message édité par tet2neu le 21-07-2009 à 20:06:57
mood
Publicité
Posté le 21-07-2009 à 20:05:43  profilanswer
 

n°1907395
Pascal le ​nain
Posté le 21-07-2009 à 20:07:10  profilanswer
 

Désolé pour ce triple post :)
 
En effet, ca fonctionne nickel avec un LEFT JOIN qui lui n'exclut personne en cas d'absence.
Voila le code final :
 

SELECT space_map.*,  
       COALESCE(etoile.map_image, planete.map_image, asteroide.map_image) AS image  
FROM space_map
LEFT JOIN etoile    ON (space_map.type=1 AND space_map.id=etoile.id)
LEFT JOIN planete   ON (space_map.type=2 AND space_map.id=planete.id)    
LEFT JOIN asteroide ON (space_map.type=3 AND space_map.id=asteroide.id)
WHERE  space_map.x>0  
  AND space_map.x<20  
  AND space_map.y>0      
  AND space_map.y<20


 
Merci beaucoup pour ton aide  :hello:


Message édité par Pascal le nain le 21-07-2009 à 20:08:19
n°1907396
tet2neu
emmerdeur
Posté le 21-07-2009 à 20:08:11  profilanswer
 

de rien ;)

n°1907695
Pascal le ​nain
Posté le 22-07-2009 à 16:39:34  profilanswer
 

Encore une petite question.
C'est une requete que je dois exécuter très souvent, il faut donc que je l'optimise un max.
 
J'ai lu ici http://sqlpro.developpez.com/cours/optimiser/ (partie 9, ligne 12 du tableau) que faire un paquet de UNION est plus rapide qu'un paquet de INNER + coalesce().
 
Qu'en penses-tu ?

n°1907710
tet2neu
emmerdeur
Posté le 22-07-2009 à 17:17:52  profilanswer
 

j'en pense que dans ton cas l'union n'est pas la solution la plus performante.
Dans le lien que tu donnes, le point numéro 12 conseille bien de transformer les COALESCE en UNION, mais l'exemple donné se justifie car les données viennent toutes de la même table.
Si tu regardes le point numéro 16, ils conseillent de transformer les UNION en jointures, et l'exemple donné utilise des.... COALESCE !

 

Donc je dirais : reste comme ça ;)

 

D'ailleurs ils oublient un conseil important : préférer "UNION ALL" à "UNION" quand cela est possible


Message édité par tet2neu le 22-07-2009 à 17:19:26

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  [MySQL] Requete avec JOIN : infos dans des bases différentes

 

Sujets relatifs
Besoin d'aide pour une requête MySQL jointe + affichage (hiérachie)Requete avec somme sur valeur et filtre sur date
[MySQL]Regex dans un where[Access 2003]Créer une table à partir d'une requète
[XML/php/Mysql] Caractere chinoisProblème du connexion à BD Mysql dans un programme C
jdbc avec mysqlserveur Mysql s'arrête
générateur de Formulaire PHP ; partie intrigante, demande infos 
Plus de sujets relatifs à : [MySQL] Requete avec JOIN : infos dans des bases différentes


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR