Salut a vous , voila j'ai un GROS problème avec une requête SQL :(
Je suis entrain de développer mon tout petit premier forum , je veux récupérer le dernier message de chaque Topic.
j'ai fait la conception de la base de données (MCD/MLD) et voila mes tables :

topics ( <u>ID_TOPIC</u> , ID_CATEGORY , ID_USER , TITLE , CONTENT , CREATED , EDITED )

comments ( <u>ID_COMMENT</u> , ID_TOPIC , ID_USER , CONTENT , CREATED , EDITED )

users ( <u>ID_USER</u> , USERNAME ) /* j'ai juste met les colonnes concernées */

categories ( <u>ID_CATEGORY</u> , ID_TYPE , CATEGORY )

types ( <u>ID_TYPE</u> , TYPE )

PS : les clés primaire sont souligné , et les clés étrangère sont en gras

Voila la requête que j'ai fait et qui marche pas xD

select T.ID_TOPIC , T.ID_CATEGORY , U.ID_USER , U.USERNAME , C.ID_USER , C.ID_TOPIC , C.CREATED
from topics T , comments C , users U
where T.ID_TOPIC = C.ID_TOPIC
and C.ID_USER = U.ID_USER
group by T.ID_TOPIC
having T.ID_CATEGORY = $id_category
and C.CREATED >= all (select CREATED from comments)

PS : $id_category c'est la catégorie de Topic

Merciiii A vous , Bonne Soirée ;)

9 réponses


FIreflame
Auteur
Réponse acceptée

Bonjour a vous , et merci pour vos réponses qui m'ont vraiment bien aider pour améliorer ma requête :)
après avoir passer quelque heures j'ai bien trouver la solution :D
@Typhon : t'a requête me semble pas juste ça retourne que des résultats NULL
en plus j'ai pas compris pour quoi t'a met :

JOIN comments C2 ON C.ID_TOPIC = C2.ID_TOPIC AND C.CREATED > C2.CREATED

sinon la solution ( qui marche pour moi lol ) est :

select C.ID_COMMENT , C.ID_USER , C.ID_TOPIC , C.CONTENT , C.CREATED , T.ID_TOPIC , T.ID_CATEGORY , U.USERNAME
from comments C
join (select max(CREATED) as max_date from comments C2 group by ID_TOPIC) X
on C.CREATED = max_date
join topics T on C.ID_TOPIC = T.ID_TOPIC
join users U on C.ID_USER = U.ID_USER
group by C.ID_TOPIC
having T.ID_CATEGORY = $id_category

J'ai rajouter la colonne C.CONTENT juste pour voir le commentaire et assurer que c'est le bon

Si vous avez des questions je suis a votre disposition
Mercii pour votre aide et Bonne journée :D

regarde comment faire les jointures dans tes requêtes je pense que ça devrait pouvoir t'aider !!

Salut , je vois pas bien ou est le problème dans les jointures ! il me semble que c'est correcte , si tu veux bien m'expliquer ça serait sympa Merci :)

Tu devrais tester ta requête directement sur phpmydamin voir ce qu'il te retourne comme erreur et voir ce qui ne va pas!
Tes noms de tables sont en majuscule?
Testes aussi ta variable voir si elle te retourne bien quelque chose.

J'ai bien tester ma requête sur phpmyadmin sachant que je l'ai déja essayer avec cakephp et sa donne un résultat vide !
Les noms de mes tables sont en minuscules et la variable est juste aussi , je crois que tout est juste sauf la dernière Line :

and C.CREATED >= all (select CREATED from comments)

Je ne suis pas sur de ça

le sql ne prend pas la casse en compte?
j'aurai mi les nom des tables dans la requête en minuscule moi mais je me trompe surement!

Comme a dit Lotfi Berrahal tu devrais penché sur les jointures,
un truc de ce genre

SELECT categories.titre, topics.content, types.title, comments.content, comments.created, users.username, categories.id
FROM users INNER JOIN (types INNER JOIN ((categories INNER JOIN topics ON categories.id = topics.category_id) INNER JOIN comments ON topics.id = comments.topic_id) ON types.id = categories.type_id) ON users.id = comments.user_id
HAVING comments.created IN (SELECT MAX(created) FROM comments GROUP BY comment.category_id)
AND (categories.id)=$id_category

Essaie de construire ta requête petit à petit, plutôt que d'un coup, pour voir ou cela peut bloquer. Je te conseils aussi d'utiliser les "JOIN" pour joindre tes tables, plutôt que d'utiliser cette vieille méthode "WHERE table1.cle = table2.cle" (Qui me semble commence à être dépréciée)

Essaie avec cette requête, pour voir si tu as bien les jointures qui se font correctement entre les topics, les commentaires et les utilisateurs

SELECT T.ID_TOPIC , T.ID_CATEGORY , U.ID_USER , U.USERNAME , C.ID_USER , C.ID_TOPIC , C.CREATED
FROM comments C
LEFT JOIN topics T ON C.ID_TOPIC = T.ID_TOPIC
LEFT JOIN users U ON C.ID_USER = U.ID_USER

Si déjà ça arrive à bien joindre les différentes tables, je te conseils de procéder comme ceci pour avoir le commentaire le plus récent de chaque topics

SELECT T.ID_TOPIC , T.ID_CATEGORY , U.ID_USER , U.USERNAME , C.ID_USER , C.ID_TOPIC , C.CREATED, max(C.ID_COMMENT) AS ID_COMMENT
FROM comments C
JOIN comments C2 ON C.ID_TOPIC = C2.ID_TOPIC AND C.CREATED > C2.CREATED
RIGHT JOIN topics T ON C.ID_TOPIC = T.ID_TOPIC
LEFT JOIN users U ON C.ID_USER = U.ID_USER
GROUP BY C.ID_TOPIC

Requête plutôt très complexe, qui sélectionne belle et bien le dernier commentaire de chaque topics.
De plus cette requête prends en compte qu'il est possible d'avoir plusieurs commentaire posté au même "dernier moment" sur un même topic, et prends donc celui qui à l'identifiant le plus grand.
Et prend également en compte qu'il est possible qu'un topic n'est pas encore de commentaire, et donc lui attribut un commentaire et un utilisateur NULL. Ainsi dans ton code PHP si la valeur est NULL (pour l'id du commentaire par exemple) alors tu peux afficher "Aucun dernier commentaires pour ce topic" (Par exemple ;D).

Voilà, j'avoue avoir eut beaucoup de mal pour cette requête, mais normalement elle marche :D (J'ai testé)

Si tu veux une explication de comment la requête peut marcher (si elle marche bien) alors demande ;)

Ok ^^

J'avais pour ma part oublié cette partie dans la requête

having T.ID_CATEGORY = $id_category

Sinon ma ligne

JOIN comments C2 ON C.ID_TOPIC = C2.ID_TOPIC AND C.CREATED > C2.CREATED

Correspond dans l'idée à cette ligne de ta requête finale

join (select max(CREATED) as max_date from comments C2 group by ID_TOPIC) X

En cherchant la commentaire qui à la date de création supérieur à tout les autres, équivalent à ton max()

J'ai peut être fait quelques erreurs dans ma requête, mais normalement elle aurait du avoir le même résultat que la tienne ^^ avec en plus des valeurs NULL pour chaque topics du forum n'ayant pas de commentaires.

Mais l'important c'est que tu es trouvé une solution ;)