Requête SQL complexe

Requête SQL complexe - SQL/NoSQL - Programmation

Marsh Posté le 07-01-2010 à 01:38:33    

Bonjour à tous  :hello: ,  
 
Voilà donc, le problème est le suivant :  
 
Recherche de Requete SQL our une BDD d'achats.
J'ai une bdd avec 2 tables de chacune 3 entrées
la première table "Date" (stockes une nouvelle entrée à chaque minute) de chaque jour même si il n'y a pas d'achat: avec pour champs: ID_date, jour, heure, minute
la seconde table stock des achats (unen nouvelle entrée a chaque achat): avec pour champs: ID_date, Id_achats, argent_dépensé
 
Je voudrais faire en une seule requête SQL (qui peux avoir des requêtes imbriquées):
Obtenir le nombre d'achat et la moyenne d'argent dépensé par tranche horaire en ne retenant que les heures qui ont un nombre moyen de dépenses >10€
 
A la base, un petit innerjoin suffirais, avec une requete imbriquée comportant une condition.
Mais, ce qui m'arrache les cheveux  :pfff: , c'est : le principe de tranche horaire, je vois mal comment comptabiliser par tranche horaire.
 
Auriez vous une piste ? Ou la requête magique ? :D  
 
Je vous en serais infiniment reconnaissant  :jap:  
Merci

Reply

Marsh Posté le 07-01-2010 à 01:38:33   

Reply

Marsh Posté le 07-01-2010 à 09:39:33    

J'ai du mal a comprendre l'intéret d'avoir une table Date ? surtout si c'est pour mettre une occurence a chaque minute tout le temps ?!?!
 
Pourquoi ne pas mettre la date tout simplement dans ta table achat ?
 
pour rappel une date peut contenir jours, mois, années, heures, minutes, secondes

Reply

Marsh Posté le 07-01-2010 à 10:11:15    

De toute facon, après une jointure de table, ca revient quasiment au même. Mais si on ne crées pas une table Date, comment faire en SQL pour avoir un résultats par tranche horaire ?
 

boboss75 a écrit :

J'ai du mal a comprendre l'intéret d'avoir une table Date ? surtout si c'est pour mettre une occurence a chaque minute tout le temps ?!?!
 
Pourquoi ne pas mettre la date tout simplement dans ta table achat ?
 
pour rappel une date peut contenir jours, mois, années, heures, minutes, secondes


Reply

Marsh Posté le 07-01-2010 à 10:42:49    

bah .... tu as l'instruction "BETWEEN" par exemple
 
Select ....
From ....
Where [date] BETWEEN date1 AND date2
 
et puis avec une date si besoin tu peux aussi extraire chaque zone de la date (jour, minute, heure ...)
par exemple en utilisant un TO_CHAR([date],'MI') pour récupérer les minutes d'une date (en oracle)

Reply

Marsh Posté le 07-01-2010 à 12:32:01    

OK, mais tu/quelqu'un n'aurais pas la solution sans devoir changer la base de donnée ?
 

boboss75 a écrit :

bah .... tu as l'instruction "BETWEEN" par exemple
 
Select ....
From ....
Where [date] BETWEEN date1 AND date2
 
et puis avec une date si besoin tu peux aussi extraire chaque zone de la date (jour, minute, heure ...)
par exemple en utilisant un TO_CHAR([date],'MI') pour récupérer les minutes d'une date (en oracle)


Reply

Marsh Posté le 07-01-2010 à 15:27:53    

Rapidement je dirais une requête du genre (pour oracle tout du moins, à adpater pour les autres SGBD) :
 

select jour,  
         heure,  
         count(distinct id_achats) as nb_achat,  
         case when count(distinct id_achats) <> 0 -- on evite la division par 0
         then  
             sum(montant)/count(distinct id_achats)  
         else
             0
         end
         as panier_moyen
from DATE T1,
     ACHATS T2
where T1.id_date = T2.id_date
group by jour, heure
having case when count(distinct id_achats) <> 0 -- on evite la division par 0
          then  
              sum(montant)/count(distinct id_achats)  
          else
              0
          end > 10


 
le having te permet de poser une condition sur le résultat d'une opération d'aggregation.


---------------
Don't fuck me, I'm anonymous.
Reply

Marsh Posté le 07-01-2010 à 17:17:24    

Merci  :jap: , mais ce n'est pas encore ca ... il y a juste un problème: la moyenne n'est pas à faire sur les nombres d'achats, mais sur les tranches horaires
 

E-Nyar a écrit :

Rapidement je dirais une requête du genre (pour oracle tout du moins, à adpater pour les autres SGBD) :
 

select jour,  
         heure,  
         count(distinct id_achats) as nb_achat,  
         case when count(distinct id_achats) <> 0 -- on evite la division par 0
         then  
             sum(montant)/count(distinct id_achats)  
         else
             0
         end
         as panier_moyen
from DATE T1,
     ACHATS T2
where T1.id_date = T2.id_date
group by jour, heure
having case when count(distinct id_achats) <> 0 -- on evite la division par 0
          then  
              sum(montant)/count(distinct id_achats)  
          else
              0
          end > 10


 
le having te permet de poser une condition sur le résultat d'une opération d'aggregation.


Message édité par glandingstyle le 07-01-2010 à 17:22:19
Reply

Marsh Posté le 07-01-2010 à 17:29:21    

Code :
  1. seject d.jour, d.heure, count(id_achats) nbachats, avg(a.montant) moyachat
  2. FROM date d
  3. INNER JOIN achats a ON a.date_id = d.date_id
  4. GROUP BY d.jour, d.heure
  5. HAVING avg(a.montant) > 10
  6. ORDER BY d.jour, d.heure
 

:spamafote:

Message cité 1 fois
Message édité par MagicBuzz le 07-01-2010 à 17:30:23
Reply

Marsh Posté le 07-01-2010 à 17:52:47    

Et voila, merci pour la réponse qu'il me fallais, en fait, ce qui s'occupes de faire les tranches horaires, c'est bel et bien "group by"
 
Merci à tous pour votre aide  :love:  
 
La seule modification a apporter serais de retirer le d.jour dans le group by, ce qui permet d'avoir les moyennes sur les tranches horaires (indépendant du jour)
 
Merci encore :)
 

MagicBuzz a écrit :

Code :
  1. seject d.jour, d.heure, count(id_achats) nbachats, avg(a.montant) moyachat
  2. FROM date d
  3. INNER JOIN achats a ON a.date_id = d.date_id
  4. GROUP BY d.jour, d.heure
  5. HAVING avg(a.montant) > 10
  6. ORDER BY d.jour, d.heure


 
:spamafote:


Message édité par glandingstyle le 07-01-2010 à 17:55:15
Reply

Marsh Posté le 07-01-2010 à 17:56:09    

ah oui, effectivement :jap: j'avais pas compris la question comme ça quand tu parlais de tranches horraires (j'avais compris "heure par heure" )

Reply

Marsh Posté le 07-01-2010 à 17:56:09   

Reply

Marsh Posté le 08-01-2010 à 10:16:39    

Pour ma part j'avais un peu complexifié la requête en partant sur le fait qu'il pouvait y avoir plusieurs lignes pour un même achat (principe du ticket de caisse), d'où le fait de ne pas utiliser avg qui serait faut dans ce cas ...
 
Ca m'apprendra à lire les énoncés :D


---------------
Don't fuck me, I'm anonymous.
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed