[résolu] jointure et 'distinct'


seebz
WRInaute impliqué
WRInaute impliqué
 
Messages: 808
Inscription: 15 Avr 2007

[résolu] jointure et 'distinct'

Message le Mar Jan 06, 2009 16:52

Bonjour à tous,
J'ai un petit problème avec une requête qui doit me retourner les fiches qui ont été commentées en dernier.
La requete fonctionne bien sauf que si une fiche a reçu plusieurs commentaires récemment, elle resortira plusieurs fois dans ma liste, ce que je ne souhaite pas.

Code: Tout sélectionner
SELECT Fiche.*, Comment.created_at AS last_comment_created_at
FROM dkannu_fiches Fiche
JOIN dkannu_comments Comment ON Fiche.id=Comment.fiche_id AND Comment.online=1
WHERE Fiche.online='1'
ORDER BY Comment.created_at DESC
LIMIT 20


J'ai essayé d'utiliser DISTINCT et GROUP BY mais les résultats ne sont pas ceux attendus, une bonne âme pourra-t-elle m'aider ?

J'avoue que je suis à cours d'idée là :?
Dernière édition par seebz le Mer Jan 07, 2009 9:12, édité 1 fois.


lupuz
WRInaute discret
WRInaute discret
 
Messages: 212
Inscription: 15 Mar 2006

Message le Mar Jan 06, 2009 17:31

Tu devrais pouvoir faire une sous requete
-http://dev.mysql.com/doc/refman/5.1/en/subqueries.html


Bool
WRInaute passionné
WRInaute passionné
 
Messages: 1290
Inscription: 26 Fév 2004

Message le Mar Jan 06, 2009 17:51

Dans le cas présent je verrais plutôt un "group by". Tout ce qui t'intéresse dans "kannu_comments" c'est la date de création la plus récente.


seebz
WRInaute impliqué
WRInaute impliqué
 
Messages: 808
Inscription: 15 Avr 2007

Message le Mar Jan 06, 2009 17:58

Merci à tous les 2 d'avoir répondus :D

Pouvez-vous (si possible) me donner un exemple de requete car je ne vois pas comment faire avec la sous-requete.
J'ai aussi essayé le GROUP BY mais ca ne prenait pas forcément le dernier commentaire d'une fiche (j'ai probablement du mal m'y prendre)


YoyoS
WRInaute accro
WRInaute accro
 
Messages: 3827
Inscription: 14 Sep 2006

Message le Mar Jan 06, 2009 19:47

Salut, voila 2 requêtes. Je me suis construit une tite table fiche et commentaire et voila ce qui en ressort:

Code: Tout sélectionner
select fiche.id as idfiche, comment.date, comment.id as idcomm
from comment inner join fiche on (comment.id_fiche = fiche.id)
group by comment.id_fiche
order by comment.date DESC


ou encore, une plus farfelue moins consommatrice de mémoire mais surement plus lente:

Code: Tout sélectionner
select id as idcomm,date,(select id from fiche where id = (select id_fiche from comment where id = idcomm)) as idfiche
from comment
group by id_fiche
order by date DESC


seebz
WRInaute impliqué
WRInaute impliqué
 
Messages: 808
Inscription: 15 Avr 2007

Message le Mar Jan 06, 2009 20:15

Génial, je vais tester ça demain à la première heure, certainement la première requete car comme je suis en mutualisé je me tamponne de la consommation mémoire (joke ;))

Si ca marche, je te remercierai 1000 fois (et bool/lupuz aussi bien entendu) , sinon je me mettrai à la broderie :P


Bool
WRInaute passionné
WRInaute passionné
 
Messages: 1290
Inscription: 26 Fév 2004

Message le Mar Jan 06, 2009 20:23

sans un max() pour récupérer la date la plus récente, tu vas surtout avoir des résultats aléatoires ;)


seebz
WRInaute impliqué
WRInaute impliqué
 
Messages: 808
Inscription: 15 Avr 2007

Message le Mar Jan 06, 2009 20:45

Bool a écrit:sans un max() pour récupérer la date la plus récente, tu vas surtout avoir des résultats aléatoires ;)

Arf, des résultats aléatoire, j'en ai eu pas mal en testant diverses requetes :?

Que recommandes-tu ? ou placerais-tu le MAX() ?

Encore merci de m'aider :D

coolspot
WRInaute discret
WRInaute discret
 
Messages: 90
Inscription: 10 Déc 2007

Re: [sql] jointure et 'distinct'

Message le Mar Jan 06, 2009 21:01

seebz a écrit:Bonjour à tous,
J'ai un petit problème avec une requête qui doit me retourner les fiches qui ont été commentées en dernier.
La requete fonctionne bien sauf que si une fiche a reçu plusieurs commentaires récemment, elle resortira plusieurs fois dans ma liste, ce que je ne souhaite pas.

Code: Tout sélectionner
SELECT Fiche.*, Comment.created_at AS last_comment_created_at
FROM dkannu_fiches Fiche
JOIN dkannu_comments Comment ON Fiche.id=Comment.fiche_id AND Comment.online=1
WHERE Fiche.online='1'
ORDER BY Comment.created_at DESC
LIMIT 20


J'ai essayé d'utiliser DISTINCT et GROUP BY mais les résultats ne sont pas ceux attendus, une bonne âme pourra-t-elle m'aider ?

J'avoue que je suis à cours d'idée là :?


déjà je pense que la requete à un problème dans la jointure et que le Comment.online=1 doit se trouver apres la première close where :

Code: Tout sélectionner
SELECT Fiche.*, Comment.created_at AS last_comment_created_at
FROM dkannu_fiches Fiche
JOIN dkannu_comments Comment ON Fiche.id=Comment.fiche_id
WHERE Fiche.online='1'  AND Comment.online='1'
ORDER BY Comment.created_at DESC
LIMIT 20


Ensuite je mettrai un group by Fiche.id (ou ref ou num je sais pas quel est l'identifiant de tes fiche) pour éviter les doublons donc un truc final comme ça :

Code: Tout sélectionner
SELECT Fiche.*, Comment.created_at AS last_comment_created_at
FROM dkannu_fiches Fiche
JOIN dkannu_comments Comment ON Fiche.id=Comment.fiche_id
WHERE Fiche.online='1'  AND Comment.online='1'
GROUP BY Fiche.id
ORDER BY Comment.created_at DESC
LIMIT 20


Bool
WRInaute passionné
WRInaute passionné
 
Messages: 1290
Inscription: 26 Fév 2004

Message le Mar Jan 06, 2009 21:12

De manière générale si vous avez un GROUP BY sans le moindre appel à une fonction d'agrégation (min(), max(), avg(), count(), etc), c'est qu'il y a un pépin dans votre requête...


YoyoS
WRInaute accro
WRInaute accro
 
Messages: 3827
Inscription: 14 Sep 2006

Message le Mer Jan 07, 2009 0:07

Youps, merci bool, heureusement que tu suis :D J'ai été légèrement vite, voila la requête corrigé avec le MAX(date) et pas date :D

Code: Tout sélectionner
SELECT fiche.id as idfiche,max(date) as last,comment.id as idcom
FROM comment INNER JOIN fiche ON (fiche.id = comment.id_fiche)
GROUP by id_fiche
ORDER BY last DESC


Et les résultats du test, beaucoup plus pertinents :p


Table commentaire
Code: Tout sélectionner
   
Textes complets     id    date    id_fiche
   Modifier    Effacer    1    2009-01-06 23:59:39    1
   Modifier    Effacer    2    2009-01-06 23:48:02    3
   Modifier    Effacer    3    2009-01-06 23:48:07    4
   Modifier    Effacer    4    2009-01-06 23:42:21    2
   Modifier    Effacer    5    2009-01-06 23:53:21    3
   Modifier    Effacer    6    2009-01-06 23:48:30    1
   Modifier    Effacer    7    2009-01-06 23:48:12    2


Table Fiche

Code: Tout sélectionner
Textes complets     id
   Modifier    Effacer    1
   Modifier    Effacer    2
   Modifier    Effacer    3
   Modifier    Effacer    4


Résultat de la requête:

Code: Tout sélectionner
idfiche    last Décroissant    idcom
1    2009-01-06 23:59:39    1
3    2009-01-06 23:53:21    2
2    2009-01-06 23:48:12    4
4    2009-01-06 23:48:07    3


seebz
WRInaute impliqué
WRInaute impliqué
 
Messages: 808
Inscription: 15 Avr 2007

Message le Mer Jan 07, 2009 9:12

Je vois que certains ont bossés tard sur mon problème et je les remercie ;)

Je viens de tester et le gagnant est [..roulement de tambours..] YoyoS (avec les remarques de Bool et coolspot).
La requete finale est la suivante :
Code: Tout sélectionner
SELECT Fiche.*, MAX(Comment.created_at) AS last_comment_created_at
FROM dkannu_fiches Fiche
INNER JOIN dkannu_comments Comment
   ON Fiche.id=Comment.fiche_id
WHERE Fiche.online='1' AND Comment.online='1'
GROUP BY Comment.fiche_id
ORDER BY last_comment_created_at DESC
LIMIT 20


Je suis content que ca fonctionne, ca m'évitera d'apprendre la broderie :P
Comme promis :
Code: Tout sélectionner
$thanks_to = array('YoyoS', 'Bool', 'coolspot', 'lupuz');
for($i=0; $i<1000; $i++)
   printf('Merci à %s et longue vie à WRI !<br />', join(', ', $thanks_to));


YoyoS
WRInaute accro
WRInaute accro
 
Messages: 3827
Inscription: 14 Sep 2006

Message le Mer Jan 07, 2009 11:43

T'aurais pu nous faire une page php dédiée qu'on puisse executer avec la boucle des remerciements quand même :D


seebz
WRInaute impliqué
WRInaute impliqué
 
Messages: 808
Inscription: 15 Avr 2007

Message le Mer Jan 07, 2009 13:05

YoyoS a écrit:T'aurais pu nous faire une page php dédiée qu'on puisse executer avec la boucle des remerciements quand même :D

Suffit de demander, et ici un 'tit truc rien que pour toi :lol: (faut bien décompresser)


YoyoS
WRInaute accro
WRInaute accro
 
Messages: 3827
Inscription: 14 Sep 2006

Message le Mer Jan 07, 2009 13:08

Snirf, ca y est, j'ui zému :D


Si vous avez aimé cette discussion, partagez-la sur vos réseaux sociaux préférés :

Lectures recommandées sur ce thème :



Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 1 invité