Oracle
 sql >> Base de données >  >> RDS >> Oracle

Oracle sqlSubtract entre deux dates

Je suppose que c'est un devoir, donc quelques indices...

Tout d'abord, ne stockez jamais les dates en tant que varchar , cela vous causera, à vous et à l'optimiseur, toutes sortes de problèmes.

Deuxièmement, la date d'Oracle le type de données ne peut stocker qu'à la seconde précision, et votre chaîne a des fractions de seconde, donc vous regardez timestamp plutôt que date . Vous pouvez convertir votre chaîne en horodatage avec to_timestamp() en passant un masque de format approprié . Oh OK, je me sens généreux :

select to_timestamp(start_date, 'DD-Mon-RR HH.MI.SS.FF9 AM') from your_table;

Troisièmement, la soustraction de deux horodatages vous donnera un interval type de données, à partir duquel vous devrez extraire les informations souhaitées dans un format lisible. Recherchez ce site ou ailleurs pour la soustraction d'horodatage, mais je vous indiquerai celui-ci récent comme exemple.

La moyenne est un peu plus compliquée, vous pouvez donc convertir vos intervalles en nombres pour cela; recherchez à nouveau les questions précédentes, telles que celle-ci . La taille des intervalles, la précision dont vous vous souciez réellement et la façon dont vous souhaitez que la sortie soit formatée, etc. auront une certaine incidence sur l'approche que vous souhaitez adopter.

Si vous avez besoin d'un résultat approximatif, la réponse de @Joachim Isaksson vous donnera cela - "approximatif" en raison de l'arrondi ; une durée inférieure à une seconde apparaîtra comme zéro, par exemple. Le même effet peut être observé avec les horodatages convertis en dates, qui perdent également les fractions de seconde :

select 24*60*60*avg(
    cast(to_timestamp(step_ending_time, 'DD-Mon-RR HH.MI.SS.FF9 AM') as date)
        - cast(to_timestamp(step_starting_time, 'DD-Mon-RR HH.MI.SS.FF9 AM') as date)
    ) as avg_duration
from process_audit;

Une réponse plus précise peut être trouvée en extrayant les différents composants des horodatages, comme dans une question à laquelle j'ai lié plus tôt. Vous n'en aurez peut-être pas besoin si vous savez que vos durées sont toujours inférieures à une heure, par exemple, mais si vous en avez besoin de plus d'une (c'est-à-dire si une durée peut être supérieure à une minute), l'utilisation d'une expression de table commune intermédiaire simplifie les choses a bit :

with cte as (
    select to_timestamp(step_ending_time, 'DD-Mon-RR HH.MI.SS.FF9 AM')
        - to_timestamp(step_starting_time, 'DD-Mon-RR HH.MI.SS.FF9 AM') as duration
    from process_audit
)
select avg(extract(second from duration)
    + extract(minute from duration) * 60
    + extract(hour from duration) * 60 * 60
    + extract(day from duration) * 60 * 60 * 24) as avg_duration
from cte;

Avec deux exemples de lignes, une avec un écart d'exactement une seconde et une avec exactement 1,5 seconde, cela donne le résultat 1.25 .