Retour au blog
Faire la moyenne de sommes avec Laravel

Faire la moyenne de sommes avec Laravel

Sommaire

  1. Problématique
  2. Tutoriel vidéo
  3. Requête avec SQL
  4. Requête avec le Query Builder
  5. Conclusion

Problématique

Vous savez probablement déjà calculer des sommes. Vous savez probablement aussi calculer des moyennes.

Mais comment mixer les 2 ?!

Prenons un cas simple où vous stockez les transactions de vos utilisateurs en base de données. Vous avez donc une table users et transactions.

La table transactions contient une colonne amount pour le montant et une colonne user_id pour la clé étrangère.

Comment calculer alors la moyenne des sommes de nos utilisateurs ?

La difficulté réside dans le fait qu’on ne peut pas enchaîner 2 fonctions d’aggrégat.

SELECT AVG(SUM(amount))
FROM transactions
GROUP BY user_id

Cette requête vous envoie en prison. Rien que cet exemple hérisse les poils de mon IDE qui me notifie d’un beau Nested aggregate calls are not allowed

Tutoriel vidéo

Requête avec SQL

Restons avec SQL pour bien saisir la solution. Pour répondre à la question, il faut calculer dans un premier temps la somme dans une sous-requête, puis dans un second temps la moyenne.

SELECT AVG(total_amount)
FROM (
    SELECT SUM(amount) AS total_amount
    FROM transactions
    GROUP BY user_id
)

La sous-requête group et calcule la somme des transactions par utilisateur.

On nomme un alias total_amount pour représenter la valeur de cette somme.

Enfin, nous calculons la moyenne via AVG sur toutes les sommes par utilisateur sur ladite sous-requête.

Requête avec le Query Builder

Maintenant que notre requête SQL est correcte, passons sur Laravel !

return DB::table(
    fn ($query) => $query
        ->selectRaw('SUM(amount) AS total_amount')
        ->from('transactions')
        ->groupBy('user_id'), 'transactions')->avg('total');

Et voilà ! Nous arrivons au même résultat, encore faut-il le savoir !

Conclusion

Laravel et son Query Builder nous permettent de faire des choses incroyables. Merci à Jonathan Reinink pour cette astuce et sa PR.

N’hésitez pas à me suivre et à vous abonner à Laravel Jutsu pour plus de contenu !