Requête sur deux tables, confondre les résultats

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Requête sur deux tables, confondre les résultats

par Cyrano » 21 févr. 2006, 09:56

Je note deux défauts;
- Le noms des identifiants : petite recommandation, un champ "id" n'est pas très parlant et je te suggère de les préfixer : suj_id et msg_id; un champ suj_id sera plus évident dans la table forum_messages;
- Si le champ suj_id est du type INT dans la table forum_sujets, il doit l'être également dans la table forum_messages, or tu l'as mis en VARCHAR dans la seconde;

Ensuite, pourquoi mettre un champ "par" dans les deux tables ? Dans la mesure où tu as déjà une relation existant entre les deux tables, l'auteur n'a besoin d'être que dans une seule table. Néanmoins, j'aurais créé une troisième table forum_membres avec un champ mem_id qu'on retrouverait en clé étrangère dans forum_messages.

Le champ titre n'a pas besoin non plus d'être présent dans les deux tables, une seule fois dans la table forum_messages serait largement suffisant.

Pour extraire maintenant tous les messages dont le posteur d'origine est un membre en particulier, tu aurais alors une jointure à effectuer sur les deux tables membres et messages sans nécessité d'ajouter la table sujet si tu n'as besoin que du pseudo et de l'heure, requête qui ressemblerait alors à ceci:

Code : Tout sélectionner

SELECT mem_pseudo, msg_date FROM forum_membres AS mm, forums_messages AS ms WHERE mm.mem_id = ms.mem_id AND mem_pseudo = 'Alexbad' ORDER BY msg_date
Si tu veux seulement les messages de ce membre mais triés par sujets, alors il faut rajouter la table sujets dans la jointure avec une clause de tri supplémentaire sur les sujets :

Code : Tout sélectionner

SELECT mem_pseudo, msg_date FROM forum_membres AS mm, forums_messages AS ms, forums_sujets AS sj WHERE mm.mem_id = ms.mem_id AND ms.suj_id = sj.suj_id AND mem_pseudo = 'Alexbad' ORDER BY sj.suj_id, msg_date
Et si tu veux pointer sur un sujet particulier, alors rajoute l'identifiant du sujet:

Code : Tout sélectionner

SELECT mem_pseudo, msg_date FROM forum_membres AS mm, forums_messages AS ms, forums_sujets AS sj WHERE mm.mem_id = ms.mem_id AND ms.suj_id = sj.suj_id AND sj.suj_id = 123456 AND mem_pseudo = 'Alexbad' ORDER BY msg_date

par alexbad » 21 févr. 2006, 01:30

Oui, j'admets qu'en relisant ça demeure vague.

J'ai deux tables : une pour stocker les sujets :

Code : Tout sélectionner

CREATE TABLE `forums_sujets` ( `id` mediumint(9) NOT NULL auto_increment, `sujet` varchar(255) NOT NULL default '', `par` varchar(255) NOT NULL default '', `date` varchar(255) NOT NULL default '', `message` longtext NOT NULL, `forum` mediumint(9) NOT NULL default '0', `nbre_vu` mediumint(9) NOT NULL default '0', PRIMARY KEY (`id`) );
Le champ "sujet" contient le titre du post, le champ "par" contient l'auteur, le champ "date" contient un timestamp (bien qu'en VARCHAR 255), "message" contient le texte du post, "forum" contient le id du forum dans lequel le sujet se trouve, et "nbre_vu" le nombre de fois que le topic a été vu.

Cette table ne contient que les sujets. Par exemple, ici si on serait sur mes forums, on ne trouverait que dans cette table le premier post que j'ai fait au début. Le message que je suis en train de poster et celui de Truc serait placés dans une table "forums_messages" :

Code : Tout sélectionner

CREATE TABLE `forums_messages` ( `id` mediumint(9) NOT NULL auto_increment, `sujet` varchar(255) NOT NULL default '', `forum` varchar(255) NOT NULL default '', `message` longtext NOT NULL, `par` varchar(255) NOT NULL default '', `date` varchar(255) NOT NULL default '', `titre` varchar(255) NOT NULL default '', PRIMARY KEY (`id`) )
Le champ "sujet" contient le id du sujet (pas le titre du post, ça correspond au champ "id" dans la table forums_sujets). Ensuite, "forum" contient l'id du "forum" (très facultatif comme champ, rien à voir avec mon problème), "message" contient le texte et le reste très logique.


Résumé : Une table contient les sujets, et une autre contient les réponses avec un champ qui les associent à un sujet.

Ce système n'est très certainement pas le meilleur, j'ai surmonté tous les problèmes avec des solutions abracadabrantes par contre, si je ne trouve pas de solution à mon problème présent, je me résignerai et je reconstruirai une partie du fonctionnement des forums.

Donc, mon problème:

Quand je veux faire un listing de tous les messages d'un membre, je dois rechercher dans deux tables (forums_sujets et forums_messages). Forums_sujets contenant tous les sujets ouverts par ce membre, forums_messages contenant toutes les réponses apportées par ce membre.

Exemple:
  • Alexbad poste un nouveau sujet à 17:30
  • Alexbad poste une réponse sur un autre sujet à 17:35
  • Alexbad poste un nouveau sujet à 18:00
  • Alexbad poste une réponse sur un autre sujet à 18:10
Je voudrais qu'en cliquant sur "Voir tous les messages de Alexbad", ça m'affiche ces messages dans cet ordre. Par contre, le dilemme : comment faire s'ils ne sont pas dans la même table pour conserver cette chronologie?

Merci, j'espère avoir été plus explicite sur la nature du problème

par Truc » 21 févr. 2006, 01:03

Désolé mais c'est pas vraiemnt clair, peut tu donner la structure des tables utilisées avec les champs nécessaires y a t-il un lien entre les tables.

Un exemple de résultat attendu aussi :wink:

Requête sur deux tables, confondre les résultats

par alexbad » 21 févr. 2006, 00:01

Salut,

Mes forums sont construits de cette manière:

-Une table avec id qui contient les sujets
-Une table avec un champ "sujet" qui contient les réponses

Ce que je veux faire, c'est afficher tous les messages d'un membre, ordonné par date, mais en confondant les résultats des deux tables.

Tout ce que je parviens à faire jusqu'à présent, c'est de faire un lien "Voir les sujets ouverts par tel membre" ou "Voir toutes les réponses apportées par ce membre". Ou encore je peux faire lister en premier tous les sujets ouverts par ce membre puis les réponses mais c'est pas ordonné par date... :?

Merci :wink: