Problème de requête SQL pour calculer des stats

Eléphanteau du PHP | 30 Messages

20 mai 2009, 22:24

Bonjour,

je me retrouve face à un petit problème... Je configure actuellement une administration à ma boutique en ligne, et je souhaiterais afficher dans les statistiques de l'administration "les meilleurs jours de vente" pour retrouver les jours où les ventes ont explosé facilement (suite éventuellement à un buzz ou autre).

Mais je me retrouve face à un problème de requete : comment faire la somme de toutes les ventes par jour automatiquement, sans rien changer dans l'admin par la suite, pour sortir uniquement les meilleurs ??

J'ai une table "commandes" qui regroupe toutes les achats, qui contient le champ "date" avec une date/heure (de ce format : 0000-00-00-00-00-00), mais autant pour faire la somme d'une journée, ce serait simple, autant calculer la somme des ventes jour par jour, pour sortir uniquement les meilleurs, je ne vois vraiment pas comment faire. Surtout sans alourdir trop la requête.

Pourtant la solution doit exister ??? Quelqu'un pour m'aider ??


Je précise que tout celà est théorique, je n'ai pas de boutique en ligne, j'apprends à développer !

Merci d'avance. Bien cordialement,
:wink:

Eléphant du PHP | 185 Messages

20 mai 2009, 22:46

SELECT DAY(date)
FROM commandes
GROUP BY DAY(date)
ORDER BY SUM(montant)DESC
LIMIT 0,5

Un truc comme ça , ça doit fonctionner. :)

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

20 mai 2009, 22:46

Si ta table commande est structurée comme ça:
Commande (id_com, id_client, id_produit, date, montant)

La requête qui calcule la somme des ventes par jour par produit est la suivante:

Code : Tout sélectionner

SELECT date, id_produit, sum(montant) as total_ventes FROM Commande GROUP BY date, id_produit ORDER BY date DESC, total_ventes DESC
La clause ORDER BY fait le classement des enregistrements par dates décroissantes (date DESC) et par totaux des ventes décroissants (total_ventes DESC)

Remarque:
L'inconvénient de la solution de savageman est que le GROUP BY DAY(date) va regrouper par numéro de jour toutes les dates mois et années confondus.
Le plus judicieux est de regrouper par la date vu que cette dernière correspond définitivement à un jour.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Eléphanteau du PHP | 30 Messages

21 mai 2009, 01:05

Merci pour ces conseils...

Deux petits hics malgré tout : je n'ai pas un format date (Y-m-d), mais un format date/heure (Y-m-d-h-n-s), hors je souhaite bien les regrouper par la date (Y-m-d). Je dois donc certainement faire un SUBSTRING ou quelque chose comme ça en plus dans la requête, pour garder uniquement les 10 premiers champs ???

Autre chose, je ne souhaite pas faire la somme des montants, en additionant tous les prix, mais voir le nombre de commandes, donc juste additionner le nombre de lignes sélectionnées. Comment faire ? Ce n'est plus SUM, mais autre chose j'imagine ???

J'ai commencé à tester mais sans succès, je ne trouve pas les bons élements, si vous avez de nouvelles pistes pour ces petits détails ce serait vraiment sympa !

Eléphant du PHP | 245 Messages

21 mai 2009, 10:50

SELECT LEFT(date,10), count(id_commande) as total_cmde_journee
FROM Commande
GROUP BY LEFT(date,10)
Dans ce code, tu selectionne le jour (si ta date est du type 2008-09-12), le nb de commandes passées ce jour là (grace à count) et tu trie cela par jour
La fonction LEFT(nom_colonne,n) de sql permet de considerer les n premiers caracteres a partir de la gauche (RIGHT(nom_colonne,n) existe aussi)
tu peut ajuter des clauses where et meme order by pour affiner ta selection.

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

21 mai 2009, 11:08

Le problème avec la fonction LEFT(), comme toute fonction qui transforme la valeur d'un champ, c'est que les indexs ne pourront pas être utilisés.

La requête sera donc forcément plus lente.
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Eléphanteau du PHP | 30 Messages

21 mai 2009, 18:25

Merci beaucoup enneite ! :D Si jamais tu as mieux que LEFT zeus, n'hésite pas, sinon tant pis c'est déjà très bien pour le moment... :wink:

Eléphant du PHP | 245 Messages

21 mai 2009, 19:55

oui c'est vrai qu'ici les index ne sont pas utilisés.
Ceci dit ...
Dans une table de commandes, on fait normalement plus d'insertions que de selections.
Les requetes qu'on a sur le site public quand les clients commandent sont surtout du type "insert".
Les types "select" se font, dans ce cas, dans l'admin par seulement une poignée d'utilisateurs.
Etant donné que les indexs doivent se régenérer dès que la table change, ils ne sont pas forcement recommandés pour les tables qui font plus de "insert" que de "select". On peut meme dire que dans ce cas, ils ralentissent les requetes plus qu'ils ne les accélèrent.

Donc dans ce cas précis d'une table d'enregistrement de commande (qui n'a pas le meme but qu'une table de proposition de produits),je ne créerais pas forcémént d'index (bien qu'une étude au cas par cas pour arreter definitivement son choix soit surement necessaire).