Aller au contenu

Soucis SQL


djp1988

Sujets conseillés

J'ai un soucis au niveau d'un sql, donc pour simplifier:

2 tables:

SUJET

-id

-nom

ARTICLES

-id_a

-nom_a

-ref_sujet

-temps_sec

temps_sec est le chiffre générer par le fonction php date('U');

Je voudrais finir avec un résultat qui montre les 5 derniers sujets donc il y a les nouveaux articles, exemple:

NOM | dernier ajout

---------------------------

SUJET 1 | 1234216544

SUJET 5 | 1234216344

SUJET 16 | 1234206523

SUJET 2 | 1234212213

SUJET 6 | 1234210235

SELECT nom, temps_sec

FROM sujet, articles

WHERE sujet.id = articles.ref_sujet

GROUP BY id

ORDER BY temps_sec DESC

LIMIT 0,5

La ou je coince c'est au niveau d'un GROUP BY, parceque le temps_sec est associé à chaque article, ce que je veux c'est retenir la valeur MAXimale de chaque ref_sujet, donc qui va me permettre de voir dans quels sujets j'ai les articles les plus récents.

Ce que fais le GROUP BY c'est prendre une valeur au hasard parmi les valeurs qu'il dispose dans "le lot" lors de son groupage.

Donc quand je ORDER BY selon cette valeur, j'aid es resultats fausses...

Je pense pouvoir contourner ce probleme avec un JOIN, mais je ne sais pas comment, ce qu'il me faut c'est faire mon GROUP BY comme avant, mais pour chaque valeur de SUJET.ID trier la MAX(temps_sec) parmi un SELECT temps_sec FROM articles WHERE ref_sujet = <le_sujet>

Lien vers le commentaire
Partager sur d’autres sites

Tout bêtement:

SELECT nom, max(temps_sec)
FROM sujet, articles
WHERE sujet.id = articles.ref_sujet
GROUP BY id
ORDER BY max(temps_sec) DESC
LIMIT 0,5

Non?

Attention cependant, c'est absolument pas optimal ça, quand le nombre de sujets/articles va grossir ça va consommer pas mal de resources (il faut que le serveur lise tous les sujets et tous les articles...). A condition d'avoir un index sur temps_sec, il est probablement possible de faire quelque chose de plus optimisé avec un select distinct bien ajusté.

Jacques.

Lien vers le commentaire
Partager sur d’autres sites

Merci, en tout cas ce SQL marche tres bien en ce qui concerne le resultat donné, c'était le MAX() dans ORDER BY, je ne savais pas que l'on pouvait l'utiliser ailleurs que dans SELECT...

Merci beaucoup

Lien vers le commentaire
Partager sur d’autres sites

Version optimisée :

SELECT nom, max(temps_sec) as max_temps
FROM sujet a inner join articles b ON a.id = b.ref_sujet
GROUP BY nom
ORDER BY max_temps DESC LIMIT 0, 5

Attention aux jointures.

Et pour info, un distinct est très très lourd pour Sql. Il vaut donc mieux passer par un group by avec les différents fonctions comme SUM, Count, AVG, Max, Min, Count Distinct etc...

Lien vers le commentaire
Partager sur d’autres sites

Je me suis peut être mal exprimé... Je disais que si le DISTINCT était si lourd c'était justement parce qu'il utilisait des mécanismes similaires au GROUP BY, qui est lui aussi très lourd. Les deux sont simplement à utiliser à bon escient.

Lien vers le commentaire
Partager sur d’autres sites

Je voulais dire : A utiliser à bon escient dans la mesure où il faut utiliser un Distinct quand il faut et pareillement avec le Group By.

C'est à dire : Ne pas utiliser un Group By quand distinct convient le mieux.

Le tout dépendant de la structure des tables. (Index, Clé etc.)

Lien vers le commentaire
Partager sur d’autres sites

A priori on est d'accord, c'est surtout ce bout de phrase qui me faisait un peu peur :

un distinct est très très lourd pour Sql. Il vaut donc mieux passer par un group by

(oui c'est sorti du contexte, mais je pense que ça peut vraiment être mal interprété, c'est tout :P)

Lien vers le commentaire
Partager sur d’autres sites

Veuillez vous connecter pour commenter

Vous pourrez laisser un commentaire après vous êtes connecté.



Connectez-vous maintenant
×
×
  • Créer...