MySQL5 : Optimisation MySQL - Multiples count conditionnels

11-07-2013
Laurent Bientz

Si vous avez réalisé des requêtes de reporting pour extraire des statistiques à partir de grosses tables, vous avez dû souvent vous y prendre en plusieurs requêtes pour arriver à constituer l'ensemble de vos statistiques, ce qui peut vite devenir pénible.

Imaginons les 2 tables suivantes :

  • news avec un statut published enum ('true','false) et une FK vers category
  • category

Si vous souhaitez obtenir le nombre total de news dans chaque category, naturellement le group by va vous venir en aide :

SELECT
||t||n.category_id,
||t||COUNT(*) AS total_news
FROM 
||t||news n
||t||LEFT JOIN category c ON n.category_id = c.category_id
GROUP BY
||t||n.category_id
ORDER BY
||t||total_news DESC

Ce qui va vous donner l'ensemble des category ainsi que le nombre de news dans chacune de ces category.

Sauf que c'est là que cela se corse, vous aimeriez bien savoir en même temps, parmi ces news de toutes ces category, combien de news sont publiées vs sont non publiées.

Instinctivement, vous voudriez ajouter des count() avec des where, sauf que MySQL ne permet pas de mettre des clauses dans la fonction count(), seulement au niveau du where, dans lequel vous ne pourrez pas grouper sur plusieurs clauses.

Vous allez vous résoudre à le faire en plusieurs requêtes et c'est là que nous intervenons en vous proposant cette solution alternative :

SELECT
||t||n.category_id,
||t||COUNT(*) AS total_news,
||t||SUM(IF(n.news_published = 'true', 1, 0)) AS total_news_published,
||t||SUM(IF(n.news_published = 'false', 1, 0)) AS total_news_not_published
FROM 
||t||news n
||t||LEFT JOIN category c ON n.category_id = c.category_id
GROUP BY
||t||n.category_id
ORDER BY
||t||total_news DESC

La solution consiste à transformer notre count where utopique en une somme conditionnelle où nous influons directement sur la somme en effectuant notre test dedans et en forcant le +0 ou le +1.

Le résultat est donc bien conforme à ce que nous souhaitions :

Pratique non ?

Karligash - 2013-09-02 21:01:14
Thanks for your free testing prorgam, I find the free testing prorgam for a long long time ago.I just start to learn 倉頡輸入法, very very slowly and need to use much time to think.

Expérience utilisateur

Wandi vous propose de découvrir une nouvelle approche de la navigation sur un site web...
Êtes-vous prêt ?

Démarrer l'expérience