Précédent   Forum des professionnels en informatique > Bases de données > Oracle > PL/SQL
PL/SQL Forum d'entraide sur le PL/SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 22/11/2011, 16h30   #1
Invité de passage
 
Homme
Inscription : juin 2011
Messages : 12
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations forums :
Inscription : juin 2011
Messages : 12
Points : 4
Points : 4
Par défaut Opérations sur des heures

Bonjour à tous,

Je vous expose mon problème :

j'ai une table avec des heures au format hh:mm:ss (colonnes de type varchar2) et j'aimerais faire des soustractions d'heures basiques du genre :

06:20:00-05:10:00 = 70:00 en gros (je passe du format hh:mm:ss au format mm:ss).

Mon problème est que je ne suis pas sur 24h mais sur 25 ou 26 (je peux avoir des heures du type 26:42:12 par exemple).

Actuellement, je transforme donc mes heures en secondes à coup de to_number(substr(heure,1,2)*3600 + substr(...)), je fais ma soustraction et je reconvertis en format mm:ss à coup de to_char(floor(secondes/60)) || ':' || to_char(mod(secondes,60))...

Ca marche, mais sachant que j'aimerais faire cette soustraction directement dans le Select de ma requete, cela me fait beaucoup de blabla pour pas grand chose au final.

Quelqu'un aurait-il une solution plus élégante ou cela n'est-il tout simplement pas possible?

Merci d'avance pour vos réponses.
Pr3ToriA est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2011, 17h32   #2
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 686
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 686
Points : 10 435
Points : 10 435
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Vous pouvez travailler avec le type INTERVAL, mais ça demande quelques manipulations qui au final ne seront pas forcément beaucoup plus simple que ce que vous avez là.

Compte-tenu que vos heures peuvent dépasser 24, je n'ai trouvé que le format ISO pour convertir.
Ensuite la soustraction est simple, mais il faut encore reconvertir le résultat dans une chaîne de caractères.

Je détaille ici toutes les manipulations :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
WITH SR1 AS
(
SELECT '26:42:12' AS it1, '06:20:00' AS it2 FROM dual
)
  ,  SR2 AS
(
SELECT 'P0DT' || substr(it1, 1, 2) || 'H' || substr(it1, 4, 2) || 'M' || substr(it1, -2) || 'S' AS itv1
     , 'P0DT' || substr(it2, 1, 2) || 'H' || substr(it2, 4, 2) || 'M' || substr(it2, -2) || 'S' AS itv2
  FROM SR1
)
  ,  SR3 AS
(
SELECT to_dsinterval(itv1) - to_dsinterval(itv2) AS itv_diff
  FROM SR2
)
SELECT to_char(24 * 60 * extract(day    FROM itv_diff)
             + 24 *      extract(hour   FROM itv_diff)
             +           extract(minute FROM itv_diff), 'fm99900')
       || ':' ||
       to_char(extract(second FROM itv_diff), 'fm00') AS "MM:SS"
  FROM SR3;
À votre place, je garderai vos transformations et je les collerai dans une vue, ça devient transparent pour la suite du select.
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/11/2011, 09h01   #3
Invité de passage
 
Homme
Inscription : juin 2011
Messages : 12
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations forums :
Inscription : juin 2011
Messages : 12
Points : 4
Points : 4
Merci pour votre réponse, ce n'est effectivement pas vraiment plus simple
Par contre je n'avais pas pensé à la vue, qui serait une solution intermédiaire. Je vais voir si je peux me diriger dans ce sens.
Pr3ToriA est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/11/2011, 14h18   #4
McM
Expert Confirmé Sénior
 
Inscription : juillet 2003
Messages : 3 440
Détails du profil
Informations forums :
Inscription : juillet 2003
Messages : 3 440
Points : 4 183
Points : 4 183
Tu peux mettre tout ton calcul dans le select, sinon, une petite fonction ferait la même chose

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT deb, fin,
       TRUNC((  TO_NUMBER(SUBSTR(fin, 1, 2)) * 3600 + TO_NUMBER(SUBSTR(fin, 4, 2)) * 60 + TO_NUMBER(SUBSTR(fin, 7,2)) 
       - TO_NUMBER(SUBSTR(deb, 1, 2)) * 3600 - TO_NUMBER(SUBSTR(deb, 4, 2)) * 60 - TO_NUMBER(SUBSTR(deb, 7,2))
       ) / 60) ||':'|| 
       LPAD(MOD(TO_NUMBER(SUBSTR(fin, 1, 2)) * 3600 + TO_NUMBER(SUBSTR(fin, 4, 2)) * 60 + TO_NUMBER(SUBSTR(fin, 7,2)) 
       - TO_NUMBER(SUBSTR(deb, 1, 2)) * 3600 - TO_NUMBER(SUBSTR(deb, 4, 2)) * 60 - TO_NUMBER(SUBSTR(deb, 7,2))
       , 60), 2, '0')        
       AS diff
FROM (SELECT '05:10:00' AS deb, '06:20:00' AS fin FROM dual
UNION SELECT '05:10:10', '26:20:00'  FROM dual)
 
DEB	FIN			DIFF
05:10:00	06:20:00	70:00
05:10:10	26:20:00	1269:50
__________________
More Code : More Bugs. Less Code : Less Bugs
McM est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 17h23.


 
 
 
 
Partenaires

Hébergement Web