2012-02-25 5 views
1

L'utilisation de Rails ActiveRecord, je veux calculer l'heure entre deux champs datetime dans la même rangée. La différence entre les deux dates pourrait être de quelques secondes à plusieurs heures, et pourrait s'étendre à la mi-nuit. Un nombre de secondes représentant la différence serait dandy. Utilisez les deux sqlite et postgress.calculer le temps entre deux datetime - ActiveRecord/SQL/Heroku

En jouant avec sqlite, ce qui suit donne juste 0 pour le calcul. (À la fois "solved_at" et "started_at" sont de type "datetime", et "solved_at" est plus tard que "started_at")

SELECT (datetime(solved_at) - datetime(started_at)) FROM "schedules"; 

Autres expressions pour aider les autres recherche temps de calcul entre deux calculate temps entre calculer le temps écoulé entre calculer le temps écoulé entre calculer la durée entre deux calculer la durée entre les deux temps dérive entre deux temps dérive entre dériver elap sed temps entre dériver le temps écoulé entre les deux durée dérive entre deux durée dérive entre deux déterminer le temps entre deux déterminer le temps entre déterminer le temps écoulé entre déterminer le temps écoulé entre déterminer la durée entre deux déterminer la durée en entre deux

+2

Je déteste les phrases SEO snippet tellement, tellement beaucoup. La modération devrait ramasser les doublons par les utilisateurs qui ne peuvent pas chercher très bien. – millimoose

+0

probablement que ActiveRecord ne le fait pas, et que SQL différent est nécessaire pour Sqlite3 et Postgres. Alors aura une logique qui vérifie si Rails.env.development? (Sqlite3) ou Rails.env.production? (Heroku) et SQL spécifique en conséquence – Straff

Répondre

2

quelque chose comme ceci:

dur_sql = "strftime('%s',solved_at) - strftime('%s',started_at)" unless Rails.env.production? # sqlite in dev and test modes  
dur_sql = "extract(epoch from solved_at - started_at)" if Rails.env.production? # heroku with postgres 

select_clause = "count(*) as count, env, case_type, date(started_at) as started_at_date, " + "AVG(#{dur_sql}) as avg_dur, MIN(#{dur_sql}) as min_dur, MAX(#{dur_sql}) as max_dur" 

group_clause = "env, case_type, date(started_at)" 

where_clause = ... 
grouped_stuff = Schedule.select(select_clause).where(where_clause).group(group_clause) 
0

Dans PostgreSQL, vous pouvez obtenir la différence de temps en exécutant:

SELECT AGE(TIMESTAMP date1, TIMESTAMP date2); 

Cela donne un intervalle, afin de le transformer en quelques secondes vous exécutez:

EXTRACT(EPOCH FROM interval) 

Exemple:

SELECT EXTRACT(EPOCH FROM AGE(TIMESTAMP '1957-06-13 13:43:22', TIMESTAMP '1965-03-12 10:00:00')); 
date_part 
------------ 
-244131398 
(1 row) 
+0

sqlite> sélectionnez AGE (solved_at, started_at) à partir des programmes; Erreur: pas une telle fonction: AGE – Straff

+0

mais cela m'a fait penser ...sqlite> SELECT strftime ('% s', solved_at) - strftime ('% s', started_at) des plannings; On dirait qu'il donne de bons résultats, mais pas ActiveRecord en soi, et peut ne pas être PostgreSQL (va vérifier et mettre à jour plus tard) – Straff

+0

ressemble à strftime n'est pas pour Postgreql: http://stackoverflow.com/questions/5566530/sqlite-to- postgres-heroku-date-heure – Straff

1

est ci-dessous, mais pas la performance efficace, il devrait vous donner résultat escompté.

Schedule.all.collect{|s| s.solved_at - s.started_at} 

L'approche recommandée est de le faire dans la requête elle-même au niveau db.

1

en Ruby, schedule.solved_at - schedule.started_at retournera la distance de temps en secondes

Questions connexes