2013-01-04 5 views
2

Dans mon PostgreSQL DB sont des documents de l'application Rails contenant les prix horaires pour les 10 dernières années:Une requête avancée Date de regroupement Dilemna

10 (24 x 365) de ceux-ci: « 31/12/2012 01:00:00 », « 11.99 »

La requête suivante, les prix des groupes par jour, la moyenne des prix dans ces groupes par jour pour créer des moyennes de prix quotidiens, et retourne « jour », « paires moyennes quotidiennes » pour chaque jour:

HourlyPrice.average(:price, :group => "DATE_TRUNC('day', date)") 

Le problème est que les prix horaires de mes données source reflètent le prix de l'heure précédente. Ainsi, dans ma source de données .CSV, le jour commence à l'heure 01:00:00 et se termine à l'heure 24:00:00.

Ceci est en conflit avec la façon dont PostgreSQL aime enregistrer les enregistrements dans sa colonne DateTime. Lors de l'importation des données CSV, PostgreSQL convertit mes enregistrements contenant l'heure 24:00:00 à 00:00:00 du jour suivant.

Cela supprime la précision de ma requête de moyenne ci-dessus. Pour corriger la requête, je veux toujours regrouper par jour, mais compenser 1 heure. Ainsi, la plage moyenne commence à 01:00:00 et se termine avec la valeur 00:00:00 du jour suivant.

Est-il possible d'ajuster la requête ci-dessus pour refléter cela?

+0

Vous ne devez pas ajouter PostgreSQL, Rails, etc. ActiveRecord dans le titre de votre question. Les gens peuvent voir de quoi parlent les tags. Ajoutant également votre nom et "Merci" n'est pas nécessaire, même [indésirable] (http://stackoverflow.com/faq#signatures). Ces choses ont été supprimées de certaines de vos autres questions, alors j'ai pensé que je devrais vous en faire part. A part ça, bonne question. – Mischa

+1

Pourquoi ne corrigez-vous pas vos données CSV pour correspondre à ce que la base de données attend pendant que vous l'importez? Vous ne voulez pas que votre base de données vous ment et vous ne voulez pas mentir à votre base de données. –

+0

Merci mu. Votre contribution est toujours appréciée. J'ai pensé à ça. Cependant, mes données proviennent d'une source fiable (agence publique) et je ne veux pas casser leur format. Si je déplace toutes les dates d'une rangée pour convenir au comportement db, et que quelqu'un contre-interroge la date d'un enregistrement de prix avec la source pour vérifier l'exactitude, il serait éteint, inspirant la confusion et la méfiance. Peut-être devrais-je convertir ma colonne de date de DateTime en chaîne et réessayer cette requête? – ac360

Répondre

1

Vous pouvez soustraire une heure de date avant d'appliquer la fonction DATE_TRUNC à elle, comme ceci:

HourlyPrice.average(:price, :group => "DATE_TRUNC('day', date - INTERVAL '1 hour')") 
+0

Vous avez raison Andriy. Je vous remercie. Cette requête passe maintenant par des milliers d'enregistrements et crée des moyennes parfaitement :) Beau travail. Merci encore. – ac360