SGBD/SQL/ALIAS

SGBD/SQL/ALIAS - SQL/NoSQL - Programmation

Marsh Posté le 14-04-2008 à 17:34:54    

Bonjour,
j'ai contruit une table (position) qui contient les differentes positions des voitures  contenant les colonnes suivants: nom_voiture, etat_voiture(active ou inactive), latitude, longitude, vitesse, date, heure.
je veux calculer le temps de conduite d'une voiture entre deux dates a l'aide d'une requete SQL integré dans une page jsp; càd calculer la somme de temps d'activité du voiture,  
 
J'ai essayé avec la requette suivante:
SELECT date,max (vitesse),avg (vitesse),min (heure),max(heure) from  position where ((date between '"+datedebut+"' AND '"+datefin+"') AND (nom='"+nom_voiture+"')) GROUP BY date ;
elle affiche tous les champs demandés, mais je veux qu'elle calcule aussi la durée d'activité du voiture(ou l'etat est active).
Sachant que je travail avec postgresql 8.2.5, et postgis 1.3 et eclipse europa( pour les pages jsp)
Merci d'avance.


Message édité par tomhanks le 17-04-2008 à 11:30:33
Reply

Marsh Posté le 14-04-2008 à 17:34:54   

Reply

Marsh Posté le 15-04-2008 à 09:19:15    

Vous n'avez aucune réponse?

Reply

Marsh Posté le 15-04-2008 à 16:26:44    

Si non, ya t-il une autre méthode pour calculer la période d'activité?

Reply

Marsh Posté le 15-04-2008 à 17:18:31    

Bonjour,
je ne suis pas expert mais je n'ai pas très bien compris votre demande. En fait vous voulez afficher les mêmes informations lorsque la voiture est active ?
 
Dans ce cas pourquoi ne pas faire une deuxième requête avec en plus "AND etat_voiture = 'active' " ?

Reply

Marsh Posté le 16-04-2008 à 09:03:55    

je vais t'expliquer un peu plus;
une voiture peut etre active ou inactive, supposons que je veux calculer la periode d'activité d'une voiture durant la journée du 16/04/2008;  
ma table position contient des trucs comme ça:
 à  8:00: etat=active
     09:00: etat=active
     10:00: etat=inactive
     11:00: etat=active
     12:00: etat=inactive
     14:00: etat=active
     15:00: etat=active
     16:00: etat=inactive
     17:00: etat=active
     18:00: etat=inactive
     et d'auters champs( vitesse, latitude, longitude...)
=> la période d'activité est (10-8)+(12-11)+(16-14)+(18-17)= 6 heures
c'est la période d'activité d'une voiture durant la journée du 16/04/2008.
je veux faire une requete SQL qui permet de calculer cette periode (periode de conduite).


Message édité par tomhanks le 16-04-2008 à 09:06:52
Reply

Marsh Posté le 16-04-2008 à 09:31:37    

ben si j'ai bien compris c'est le nombre de ligne pour lesquelles le champs état= active

Reply

Marsh Posté le 16-04-2008 à 10:27:01    

Je pense comme casimimir... peut-etre que ça pourrait marcher avec un
"select count(*) where etat_voiture='active' " (requête à compléter bien évidemment).
 
Par ailleurs j'ai du mal à comprendre le mode de calcul pour la période d'activité.... pourquoi faire un (10-8) au lieu d'un (9-8) ?
 

Reply

Marsh Posté le 16-04-2008 à 12:01:31    

pourquoi faire un (10-8) au lieu d'un (9-8) ?  
==> c'est juste un exemple normalemnet l'etat du voiture entre 9 et 10 est active, de plus les intervalles de temps seront de l'ordre de quelques minutes.
 
"select count(*) where etat_voiture='active' " (requête à compléter bien évidemment).  
===>ne donne rien, et ce n'est pas de cette méthode!!!!
si par exemple je veux calculer le temps de conduite d'une voiture entre 14/04/200 et le 16/04/2008, je pense qu'il faut calculer tout temps ecoulé=72 heures puis je calcul le temps d'inactivité (où l'etat du voiture est inactive), enfin je soustraire l'un de l'autre pour trouver le temps de conduite.
je pense qu'elle clair maintenant?
avez vous une idée comment transformer ça en une requete SQL?
 

Reply

Marsh Posté le 16-04-2008 à 12:30:55    

ha oui, mais ton exemple était limité, vu comme ca je pensais qu'il n'y avait une ligne par heure.
 
pas moyen de changer ton modèle? parceque en réalité il est assez pourri la, une ligne avec heure de début-heure de fin aurait été bien plus efficace.
 
parceque la en sql standard ca va donner des requetes imbriquées moches et a refaire pour chaque question, a moins que postgresql ne dispose de fonctions analytique style lag/lead en oracle.

Reply

Marsh Posté le 17-04-2008 à 09:07:30    

casimimir a écrit :

ha oui, mais ton exemple était limité, vu comme ca je pensais qu'il n'y avait une ligne par heure.
 
==>pas forcemenet par heure, il peut etre une ligne chaque minute.
 
 
pas moyen de changer ton modèle? parceque en réalité il est assez pourri la, une ligne avec heure de début-heure de fin aurait été bien plus efficace.
 
==> c'est une application de geolocalisation, le GPS va envoyer de données(nom_voiture, heure_debut,heure_fin,etat,vitesse,latitude,longitude,...) que je devrai les enregister dans une table puis faire un calcul du vitesse moyenne, periode d'activité...
 
parceque la en sql standard ca va donner des requetes imbriquées moches et a refaire pour chaque question, a moins que postgresql ne dispose de fonctions analytique style lag/lead en oracle.


 
==>que pensez vous des alias
il ya quelqu'un qui ma proposé de faire une sous-requête (affectée à un alias par commodité) qui va permettre de calculer cette durée d'inactivité, et englober toute la requete dans une requete mère qui permettra de faire la soustraction temps actif - temps inactif.
qui va donner quelque chose comme ça:
 
select *tous les champs qui vous interessent*, (temps_total - temps_inactif) from (SELECT A.date, A.max(vitesse), A.avg(vitesse), A.min(heure) , A.max(heure), (A.max(heure) - A.min(heure)) as temps_total, B.temps_inactif from positions A, (*requête qui ramène le temps inactif pour la voiture voulue*) B where ((date between '"+datedebut+"' AND '"+datefin+"')AND (etat_voiture='active')AND(nom='"+nom_voiture+"')) GROUP BY date) ;
 
mais je l'ai pas compris, elle est incomplete!!!
quelqu'un peut m'aider en reformulant cette requette?
Merci
Cordialement
Tomhanks
 
 

Reply

Marsh Posté le 17-04-2008 à 09:07:30   

Reply

Marsh Posté le 18-04-2008 à 11:06:23    

Aucune idée?

Reply

Marsh Posté le 18-04-2008 à 16:08:31    

Je pense que se sont des choses banales pour quelqu'un qui maitrise la SGBD!!
?
 

Reply

Marsh Posté le 18-04-2008 à 16:32:13    

banal, banal, faut le dire vite.
 
c'est le genre de trucs que demandent les gens qui savent pas à quel point ils nous emmerdent avec leurs besoins à la con.
 
bref, la piste est bonne, tu dois juste faire une requête en tapant deux fois dans ta table, avec pour jointure m1.date > m2.date
et une sous-requête toujours sur la même table pour que m1.date soit filtré de façon à ne garder que le min() qui soit > que m2.
 
à ce moment, tu récupères deux colonnes m1.date et m2.date, qui correspondent au début et à la fin de chaque période. t'as plus qu'à ensuite mesurer le temps entre les deux, et vérifier l'état de m1 pour savoir si c'est une période d'activité ou non.
 
ceci dit, à la base, parceque tu es censé t'être rendu compte que ton modèle était tout sauf adapté à ta demande, tu ferais mieux de péter ton modèle afin de stocker datdeb et datfin dans la même ligne.
 
et si "oh mon dieu je peux pas toucher le MCD", alors fait au moins une vue...

Reply

Marsh Posté le 18-04-2008 à 16:39:33    

casimimir a écrit :

pas moyen de changer ton modèle? parceque en réalité il est assez pourri la, une ligne avec heure de début-heure de fin aurait été bien plus efficace.


+1. Avec le modèle que tu proposes, c'est trés compliqué.

tomhanks a écrit :

Je pense que se sont des choses banales pour quelqu'un qui maitrise la SGBD!! ?


Tu penses mal...

 

Cependant il y a une solution, mais elle est assez compliquée :

  • Tu crées une table temporaire identique à ta table d'origine mais trier par date et heure avec une colonne incrément en plus
  • Tu écris une requête qui va te permettre de comparer la table temporaire avec elle même mais pour la ligne précédente.

En gros ta table temporaire doit ressembler à ca :
1 voitureA 8:00: etat=active
2 voitureA 09:00: etat=active
3 voitureA 10:00: etat=inactive
4 voitureA 11:00: etat=active
5 voitureA 12:00: etat=inactive
6 voitureA 14:00: etat=active
7 voitureA 15:00: etat=active

 

L'idée est de lier la ligne 4 avec la 5 en faisant 4 = 5-1

 

Le sql donnera qqch comme ca :

Code :
  1. SELECT A.nom_voiture, A.etat, A.heure AS debut, B.heure AS fin
  2. FROM table_temporaire A INNER JOIN table_temporaire B
  3. ON A.increment = (B.increment - 1)
  4. WHERE A.etat = 'active'

 



Message édité par babasss le 18-04-2008 à 16:40:10

---------------
Feedback : http://forum.hardware.fr/hfr/Achat [...] 2666_1.htm
Reply

Marsh Posté le 18-04-2008 à 16:47:09    

euh...
 


ACTIVITE
----------
voiture_id
heure
etat


 
Pas testé, mais je dirais qu'en faisant ma solution, même si ça reste un gros bordel, je retrouve le temps d'activité total de la voiture "1" de cette façon :
 

Code :
  1. SELECT sum(a2.heure - a1.heure) temps, a1.etat
  2. FROM activite a1
  3. INNER JOIN activite a2 ON a2.voiture_id = a1.voiture_id
  4. WHERE a2.heure = (SELECT min(a3.heure) FROM activite a3 WHERE a3.voiture_id = a1.voiture_id AND a3.heure > a1.heure)
  5. AND a1.voiture_id = 1
  6. GROUP BY a1.etat


 
Avec un peu de pot, ça marche même du premier coup.
M'enfin niveau bitable, on fait mieux...
 
Donc à la limite, si le modèle est vraiment impossible à changer, il faut au moins faire une vue qui fait cette merde, en espérant ne jamais avoir trop de lignes... Parceque niveau perfs... 3 jointures sur une même table avecdeux niveaux d'aggrégation, hmmmm, ça se mange sans faim :D


Message édité par MagicBuzz le 18-04-2008 à 16:48:49
Reply

Marsh Posté le 18-04-2008 à 17:16:32    

Je vais essayer, merci

Reply

Sujets relatifs:

Leave a Replay

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