Requête en jointure

Requête en jointure - SQL/NoSQL - Programmation

Marsh Posté le 16-12-2008 à 22:40:01    

Bonjour,

 

Tout d'abord désolé de ma question de noob, mais je n'arrive pas à réaliser une requête.
Je vous explique le topo : j'ai un site ou l'on peut s'inscrire et enregistrer des personnages. On peut avoir plusieurs personnages par compte.
Il est possible de participer à des expéditions, pour cela on inscrit un ou plusieurs de ses personnages.
J'aimerais afficher en page d'accueil une alerte lorsqu'une expédition à laquelle un ou plusieurs personnages nous appartenant se rapproche (moins de 3 jours). Je n'arrive pas à faire ma requête, je bloque  :( .
Je vous décris mes tables :
J'ai une table "dungeon" contenant des expéditions, avec un "id" en clé unique.
J'ai une table "dungeonmembers" contenant juste 3 champs, un champ "id" en unique, un champ "dungeonid" et un champ "characterid", respectivement pour l'id de l'expédition et l'id du personnage.
Pour finir, j'ai une table "characters" qui contient un id unique, et un champ memberid pour la liaison au compte concerné.

 

Je voudrais donc récupérer l'id de l'expédition (dans la table dungeon) ou au moins un de mers personnages est inscrit. J'ai essayé avec des IN mais apparemment 2 IN ne fonctionnent pas dans la même requête  :??:
Voici la requête que j'ai faite et qui pose problème dans PHPMyAdmin :

Code :
  1. SELECT id,name FROM dungeon WHERE DATEDIFF(ddate,NOW()) < 3 ORDER BY ddate DESC IN (SELECT dungeonid FROM dungeonmembers WHERE characterid IN (SELECT id FROM characters WHERE memberid = 1))


Le memberid = 1 est là pour l'exemple, il est remplacé par l'id stocké en SESSION dans la requête bien sûr.
Bien évidemment, ça bug à fond les pédales (je HAIS le SQL, c'est viscéral :p).

 

Merci d'avance pour toute aide que vous pourrez m'apporter :)


Message édité par garfunk71 le 16-12-2008 à 22:54:50
Reply

Marsh Posté le 16-12-2008 à 22:40:01   

Reply

Marsh Posté le 16-12-2008 à 22:53:13    

déjà met le order by ddate DESC à la fin.
 
et puis le IN doit se faire sur un attribut
 
AND attribut IN (...)

Reply

Marsh Posté le 16-12-2008 à 22:58:22    

en fait , il faut que tu captes le concept de jointure...
 

Code :
  1. SELECT d1.id,d1.name
  2. FROM dungeon d1,
  3. dungeonmembers d2,
  4. characters c1
  5. WHERE DATEDIFF(ddate,NOW()) < 3
  6. -- rajoute devant le ddate l'alias de la table dans laquelle il est présent
  7. AND  d1.id=d2.dungeonid
  8. AND d2.characterid=c1.id
  9. AND c1.member=1
  10. ORDER BY ddate DESC
  11. --pareil rajoute l'alias devant ddate


 
 normalement , ça devrait marcher et te dépanner..

Reply

Marsh Posté le 16-12-2008 à 23:09:53    

Avec un

Code :
  1. SELECT DISTINCT d1.id, d1.name
  2. FROM dungeon d1, dungeonmembers d2, characters c1
  3. WHERE DATEDIFF( d1.ddate, NOW( ) ) <3
  4. AND d1.id = d2.dungeonid
  5. AND d2.characterid = c1.id
  6. AND c1.memberid =1
  7. ORDER BY d1.ddate DESC


Ca marche nickel chrome ! Merci pour ton intervention, j'avais pas capté le coup du renommage des tables.
Par contre, dans mes requêtes, j'ajoute un $mysql_prefix pour les gens qui souhaitent un préfixe pour les tables (oui, ce site est destiné à être distribué gratuitement :) ), je mets donc mon $mysql_prefix uniquement dans la ligne  

Code :
  1. FROM dungeon d1, dungeonmembers d2, characters c1


si j'ai bien compris ?
 
Encore merci, tu gères la fougère !

Reply

Marsh Posté le 16-12-2008 à 23:12:47    

le coup du renommage des tables c'est juste pour moins charger le code dans le where.
 
Il faut surtout que tu comprennes les jointures :)
 
par contre $mysql_prefix , je sais pas ce que c'est que ce truc :fear:
 

Reply

Marsh Posté le 16-12-2008 à 23:20:17    

C'est une variable à moi...
Chez un hébergeur gratuit, on a souvent qu'une seule base de données. Je permets donc à l'utilisateur de spécifier un préfixe aux tables de mon site pour éviter que ça soit le bordel, si jamais il a déjà des tables avec le même nom...
A l'install, si il spécifie par exemple le préfix "guido_", les tables seront créées sous la forme "guido_accounts", "guido_dungeons", etc...
C'est juste une facilité (j'ai fait comme ça, mais c'est peut-être sale je sais pas ^^" ).
Du coup ma requête ressemble à ça :

Code :
  1. FROM ".$mysql_prefix."dungeon d1, ".$mysql_prefix."dungeonmembers d2, ".$mysql_prefix."characters c1


Message édité par garfunk71 le 16-12-2008 à 23:20:42
Reply

Marsh Posté le 17-12-2008 à 09:45:25    

mais bon sang, arrétez de faire des jointures avec des WHERE [:ciler]


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 17-12-2008 à 11:01:43    

je me suis arrêté à oracle 8[:bricokilt]
 
comment ferais-tu avec des JOIN ?


Message édité par toji le 17-12-2008 à 11:05:05
Reply

Marsh Posté le 17-12-2008 à 11:10:01    

Code :
  1. SELECT d1.id,d1.name
  2. FROM dungeon d1 INNER JOIN dungeonmembers d2 ON d1.id = d2.dungeonid
  3.                INNER JOIN characters c1 ON d2.characterid = c1.id
  4. WHERE DATEDIFF(ddate,NOW()) < 3
  5. AND c1.member=1
  6. ORDER BY ddate DESC


Message édité par Harkonnen le 17-12-2008 à 11:10:41

---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 17-12-2008 à 14:40:17    

Désolé, mais c'est quoi l'avantage de ta technique Harkonnen ?
C'est un mini site de guilde qui n'est pas destiné à supporter plus d'une vingtaine de comptes connectés, donc niveau charge j'ai VRAIMENT beaucoup de marge...

Reply

Marsh Posté le 17-12-2008 à 14:40:17   

Reply

Marsh Posté le 17-12-2008 à 14:45:01    

je trouve le WHERE particulièrement dégueulasse et ça n'a rien à voir avec la sémantique de la jointure :
- quand tu as plein de WHERE dans ta requête, c'est plus dur de faire le distingo entre les WHERE filtrants et les WHERE de jointure
- un WHERE est fait pour filtrer, pas pour élargir
- si tu vires le WHERE à des fins de tests en oubliant de virer la table jointe dans le FROM, le SGBD ne te pète pas d'erreur. tu te retrouves avec un produit cartésien, qui peux mettre à genoux ton serveur
- ....
bref, le WHERE est à proscrire pour les jointures


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed