MySQL, les fonction COUNT, AVG, SUM
Mais j’ai remarqué que de nombreux développeurs se focalisent sur le coté programmatique (PHP, Python, java, etc) au détriment de la modélisation ou des requêtes SQL. C’est une erreur. SQL permet souvent de faire en 1 seule requête et de manière plus performante ce qu’il faudrait 1 page de code pour réaliser.
Les fonctions COUNT, AVG, SUM, etc. (fonctions d’agrégation) sont indispensable dès lors qu’on veut faire un peu d’analyse sur les données présentes dans une base. C’est à dire dès qu’elle sert à autre chose qu’à stocker des commentaires de forum.
Dans ce qui suit je n’ai volontairement pas utilisé de sous-requêtes qui ne sont pas disponibles dans MySQL avant la version 5. C’est quelque part un peu limitant.
Les exemples qui suivent utilisent le schéma de la base OS Commerce.
Pour récupérer le nombre d’enregistrements dans une table
SELECT COUNT(*) FROM customers
Retourne le nombre d’enregistrements dans la table customers.
Déterminer un nombre de lignes “uniques”
Par exemple le nombre de clients qui ont commandé.
SELECT COUNT(DISTINCT customers_id) FROM orders
La où ça commence à être un peu plus intéressant c’est lorsque qu’on souhaite déterminer quelque chose du style “le nombre de … par …”.
Le nombre de commandes par client
SELECT customers_firstname, customers_lastname,
COUNT(o.orders_id) AS nb
FROM customers c
LEFT OUTER JOIN `orders` o
ON c.customers_id = o.customers_id
GROUP BY c.customers_id
ORDER BY nb DESC
La requête fait une jointure externe entre la table qui contient les clients et celle qui contient les commandes (externe donc elle sélectionne également les clients qui n’ont pas commandé), ensuite elle fait un “regroupement” sur le champ c.customers_id c’est à dire que pour une valeur du champ c.customers_id, le COUNT(o.orders_id) contient le nombre de lignes correspondantes dans la table orders.
Déterminer les clients qui ont commandé plus de n fois
Cela se fait très bien en utilisant la clause “HAVING”.
Cette clause permet de spécifier une condition sur une fonction d’agrégation, mettre une condition WHERE à la place ne fonctionne pas.
SELECT customers_firstname, customers_lastname,
COUNT(o.orders_id) AS nb
FROM customers c
LEFT OUTER JOIN `orders` o
ON c.customers_id = o.customers_id
GROUP BY c.customers_id
HAVING nb > 5
ORDER BY nb DESC
Faire un comptage en se basant sur une valeur “calculée”, nombre de commandes par jour
SELECT date_format(date_purchased, "%Y/%m/%d") AS date,
COUNT(orders_id) AS nb FROM `orders`
GROUP BY date_format(date_purchased, "%Y/%m/%d")
ORDER BY date_purchased
A partir de là , on peut faire tout ce qu’on veut comme requête du style nombre de commandes par mois, semaine, etc.
Ce qui précède n’est en aucune manière du SQL “avancé” mais comme j’ai vu à de nombreuses reprises en travaillant avec des développeurs “professionnels” des choses aussi délicieuses que :
Pour compter le nombre d’enregistrement dans une table :
- je fais un “SELECT * …”,
- je place les tuples récupérés dans un tableau dans le langage hôte (PHP),
- je fais un count() en PHP sur le tableau
- et HOP miracle, je sais combien j’ai d’enregistrements dans ma table !
Je ne vais pas faire un florilège des conneries que j’ai pu lire (on fait tous des erreurs) mais parfois ça dépasse l’entendement. Quoi que faire un sujet rien que sur les choses qu’on fait en 600 lignes pour s’apercevoir que c’est possible en 1 seule ce serait intéressant.
