réalisable en 1 requète ??

réalisable en 1 requète ?? - SQL/NoSQL - Programmation

Marsh Posté le 29-09-2006 à 11:32:18    

Je voudrais faire des stats sur des utilisateurs qui se connect sur une borne WIFI.
J'ai donc une table.
Cette table contient :
- identifiant de l'utilisateur, log_user_id (pour une autre table, mais on a a pas besoin de la lié à la table utilisateur)
- une date de connexion, log_date (timestamp UNIX)
- une date de fin de connexion, log_date_end (ou plutot de session de connexion)
 
Je voudrais, pour 1 un mois X, connaitre le nombre MAX de connecté EN MEME TEMPS par jour. Sachant qu'un utilisateur a pu se connecter plusieurs fois dans la journée
 
Voici une requete qui compte le nombre de personnes qui se sont connecté au moins une fois dans une journée :

Code :
  1. SELECT DAY(FROM_UNIXTIME(log_date)) AS day, COUNT(DISTINCT log_user_id) AS count
  2.   FROM connect_wa_logs WHERE MONTH(FROM_UNIXTIME(log_date)) = $mois GROUP BY day


ca donne ca par exemple si j'affiche chaque ligne de résultat :

Code :
  1. array (
  2.   day => 1,
  3.   count => 2
  4. )
  5. array (
  6.   day = 4,
  7.   count => 5
  8. )
  9. ...


Mais pas a voir avec ce que je voudrais.
Est-ce fesable en une requète ? ou 2 ? Ou alors pt etre qu'une requete et du parsing PHP serait plus approprié ?
Merci
 
EDIT : j'utilise MYSQL > 5


Message édité par nORKy le 29-09-2006 à 11:35:26
Reply

Marsh Posté le 29-09-2006 à 11:32:18   

Reply

Marsh Posté le 29-09-2006 à 12:57:13    

oui, c'est possible avec les sous-requêtes (ou requêtes imbriquées) : on met un SELECT dans la clause where

Reply

Marsh Posté le 29-09-2006 à 13:42:54    

Tu veux savoir combien de personnes se sont connecté en même temps, par tranche horraire (afin d'en récupérer le max) ?
 
Parceque ta requête ressemble bien au premier, alors que tu as l'air de demander le second.
 
A priori, je pense que tu peux en effet faire ça en une seule requête (moyennant requête imbriquée, comme a indiqué rufo).
 
Par contre, je sens que tu vas t'amuser, ça m'a pas l'air super simple à faire ^^

Reply

Marsh Posté le 29-09-2006 à 13:52:09    

Je sais que c'est pas super simple, c'est pour ca que je pose la question :-)
 
Sinon, la syntax pour remettre un SELECT dans le WHERE c'est comment ?

Reply

Marsh Posté le 29-09-2006 à 14:05:21    

Ca me semble assez difficile de le faire en une requête (même compliquée avec plein de sous-requête) [:gratgrat]
(en tout cas, je vois pas comment :pt1cable: )
 
D'une manière plus procédurale, on pourrait faire comme ceci :
- on considère chaque connexion comme 2 évènements : 1 connexion et 1 déconnexion
- on construit la liste des ces évènement. En conservant pour chacun l'info comme quoi il s'agit d'une connexion ou d'une déconnexion mais sans garder de lien entre la connexion et la déconnexion de chaque user.
- en parcourant cette liste d'évènements triés par ordre croissant, il est facile de savoir à chaque instant combien de connexions simultanées il y avait : il suffit d'incrémenter 1 compteur de 1 unité à chaque connexion et de la décrémenter à chaque déconnexion.
 
Il suffit de garder le max atteint par ce compteur :)

Reply

Marsh Posté le 29-09-2006 à 14:14:50    

ouais pas simple ton affaire... comme dis par Mrbebert :
 
- connexion = +1
- déconnexion = -1
 
tu passe les événements les uns aprés les autres, et tu compte. Mais il faut être sur que tu as bien l'info de déconnexion.
De plus il faut faire ça par jour, mais en gardant les informations provenant des jours précédant (les log qui passe le cap des minuit).

Reply

Marsh Posté le 29-09-2006 à 14:36:44    

Ok, donc, pour résumer un select * et 2 boucle for PHP et quelques if (bref, gros merdier !)

Reply

Marsh Posté le 29-09-2006 à 15:33:57    

je suis sur une piste pour faire la requête, mais j'ai du mal car je tape dans une très grosse table pour mes tests, et les dates ne sont pas indexées...
 
mais à priori, j'ai la bonne solution, y'a juste qu'Oracle patine dans la choucroutte depuis 30 minutes sans rien donner comme résultat :D
 
j'ai l'impression qu'un tocard a une transaction ouverte sur une ligne de ma table et qui me bloque... tenté de créer un index et ça merde tout pareil...

Reply

Marsh Posté le 29-09-2006 à 15:35:49    

en tout cas, si ma requête marche, elle est très simple.
 
il faudra cependant adapter un peu :
- synaxe Oracle qui diffère légèrement de celle de MySQL
- moi je récupère le nombre maximum de commande ouvertes en même temps sur une période pour chaque mois.

Reply

Marsh Posté le 29-09-2006 à 15:36:57    


select substr(dateve, 1, 6) mois, max(nbcnx) nb  
from  
(  
 select e1.dateve, count(e2.numeve) nbcnx  
 from eve e2, eve e1  
 where e1.codsoc = 2  
 and e1.achvte = 'V'  
 and e1.typeve = 'CDV'  
 and e2.codsoc = e1.codsoc  
 and e2.achvte = e1.achvte  
 and e2.typeve = e1.typeve  
 and e1.dateve between e2.dateve and e2.datliv  
 and e1.dateve > '20060101'  
 group by e1.dateve  
) tmp  
group by substr(dateve, 1, 6)


 
L'index est créé, j'attends désespérément le résultat pour vérifier que c'est bon...


Message édité par MagicBuzz le 29-09-2006 à 15:39:29
Reply

Marsh Posté le 29-09-2006 à 15:36:57   

Reply

Marsh Posté le 29-09-2006 à 15:42:43    

MagicBuzz a écrit :

en tout cas, si ma requête marche, elle est très simple.
 
il faudra cependant adapter un peu :
- synaxe Oracle qui diffère légèrement de celle de MySQL
- moi je récupère le nombre maximum de commande ouvertes en même temps sur une période pour chaque mois.


 
Le nombre de commande donc ayant la meme date exact ?
Car moi, c'est pas des dates exacts, mais il faut tester des plages de dates qui se chevauchent..
Mais en regardant ta requète, je me dis que c'est fesable (mais chiant ! lol)

Reply

Marsh Posté le 29-09-2006 à 15:42:53    

Explication de ma requête :
Nombre de commandes ouvertes en même temps :
- Pour chaque création de commande, on peut déterminer le nombre de commandes ouvertes à ce moment : il suffit de rechercher toutes les commandes dont la date d'ouverture et la date de livraison encadrent la date de création de la-dite commande. C'est ce que fait mon sous-select.
 
Ensuite, il suffit de faire un max en regroupant par mois ces dates de création, et on aura pour chaque mois, le nombre maximum de commandes ouvertes en même temps durant ce mois.

Reply

Marsh Posté le 29-09-2006 à 15:43:51    

nORKy a écrit :

Le nombre de commande donc ayant la meme date exact ?
Car moi, c'est pas des dates exacts, mais il faut tester des plages de dates qui se chevauchent..
Mais en regardant ta requète, je me dis que c'est fesable (mais chiant ! lol)


ben justement, je prends pas les mêmes dates (sauf que moi, je descends pas plus loins que le jour pour a précision des dates, d'où mon choix de faire porter ma requête sur les mois plutôt que les jours)

Reply

Marsh Posté le 29-09-2006 à 15:49:33    

Bon, je peux pas vérifier que ça marche bien ma requête, ça a foutu des locks dans tous les sens et y'a la moitié des utilisateurs qui ont planté :ange:
 
En environnement de prod c'est moyen, du coup j'ai annulé ma requête :D

Reply

Marsh Posté le 29-09-2006 à 15:52:11    

MagicBuzz a écrit :

Bon, je peux pas vérifier que ça marche bien ma requête, ça a foutu des locks dans tous les sens et y'a la moitié des utilisateurs qui ont planté :ange:
 
En environnement de prod c'est moyen, du coup j'ai annulé ma requête :D


Roooo c'est pas bien de faire le souk sur un serveur en prod :D....
ceci dit si ça marche... bravo... (même si j'ais du mal à comprendre la requête)

Reply

Marsh Posté le 29-09-2006 à 16:00:34    

y'a une couille dans la sous-requête : il faut ajouter l'identifiant de la session (sinon ça fait tout péter :D)
a mettre dans le group by aussi évidement (celui de la sous-requête)
 
pour le reste, ça semble ok.
 
ça devient donc :
 


select substr(dateve, 1, 6) mois, max(nbcnx) nb  
from  
(  
 select e1.numeve, e1.dateve, count(e2.numeve) nbcnx  
 from eve e2, eve e1  
 where e1.codsoc = 2  
 and e1.achvte = 'V'  
 and e1.typeve = 'CDV'  
 and e2.codsoc = e1.codsoc  
 and e2.achvte = e1.achvte  
 and e2.typeve = e1.typeve  
 and e1.dateve between e2.dateve and e2.datliv  
 and e1.dateve > '20060101'  
 group by e1.numeve, e1.dateve  
) tmp  
group by substr(dateve, 1, 6)


 
Bon, je touche plus à rien, parceque là je fois qu'Oracle est encore à genoux, il va encore nous péter à la gueule :D
T'as intérêt à faire de jolis index :D

Reply

Marsh Posté le 29-09-2006 à 16:10:18    

(s?)norky, tu peux nous poster un extract d'une cinquantaine de lignes de ta table sous forme de "insert" ?
 
histoire que je teste tout ça (avec tes données) sur mon serveur...

Reply

Marsh Posté le 15-10-2006 à 22:51:33    

tjs en recherche de solutions ?


Message édité par swich le 15-10-2006 à 22:52:12
Reply

Sujets relatifs:

Leave a Replay

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