2010-03-09 8 views
0

Nous codons pour une application d'entreposage de données MySQL qui stocke des données descriptives (ID utilisateur, ID travail, ID machine, colonnes Début et Fin dans le premier tableau ci-dessous) associées aux données de temps et de quantité de production (colonnes Sortie et Heure). premier tableau ci-dessous) sur lequel les fonctions d'agrégat (SUM, COUNT, AVG) sont appliquées. Nous souhaitons maintenant désagréger les données de temps pour un autre type d'analyse.Transformation de données de table MySQL - comment puis-je désagréger les données de temps MySQL?

Notre conception actuelle de la table de données:

+---------+---------+------------+---------------------+---------------------+--------+------+ 
| User ID | Work ID | Machine ID | Event Start Time | Event End Time  | Output | Time | 
+---------+---------+------------+---------------------+---------------------+--------+------+ 
| 080025 | ABC123 | M01  | 2008-01-24 16:19:15 | 2008-01-24 16:34:45 | 2120 | 930 | 
+---------+---------+------------+---------------------+---------------------+--------+------+ 

dis-agrégation Retraitement que nous aimerions faire serait de transformer le contenu de la table basée sur une granularité de minutes, plutôt que l'événement de la production actuelle ("Start Event Granularité. Time "et" Event End Time "). Le retraitement résultant des lignes de table existantes ressemblerait à ceci:

+---------+---------+------------+---------------------+--------+ 
| User ID | Work ID | Machine ID | Production Minute | Output | 
+---------+---------+------------+---------------------+--------+ 
| 080025 | ABC123 | M01  | 2010-01-24 16:19 | 133 | 
| 080025 | ABC123 | M01  | 2010-01-24 16:20 | 133 |  
| 080025 | ABC123 | M01  | 2010-01-24 16:21 | 133 |  
| 080025 | ABC123 | M01  | 2010-01-24 16:22 | 133 |  
| 080025 | ABC123 | M01  | 2010-01-24 16:23 | 133 |  
| 080025 | ABC123 | M01  | 2010-01-24 16:24 | 133 |  
| 080025 | ABC123 | M01  | 2010-01-24 16:25 | 133 |  
| 080025 | ABC123 | M01  | 2010-01-24 16:26 | 133 | 
| 080025 | ABC123 | M01  | 2010-01-24 16:27 | 133 |  
| 080025 | ABC123 | M01  | 2010-01-24 16:28 | 133 |  
| 080025 | ABC123 | M01  | 2010-01-24 16:29 | 133 |  
| 080025 | ABC123 | M01  | 2010-01-24 16:30 | 133 |  
| 080025 | ABC123 | M01  | 2010-01-24 16:31 | 133 |  
| 080025 | ABC123 | M01  | 2010-01-24 16:22 | 133 |  
| 080025 | ABC123 | M01  | 2010-01-24 16:33 | 133 |  
| 080025 | ABC123 | M01  | 2010-01-24 16:34 | 133 |  
+---------+---------+------------+---------------------+--------+ 

Ainsi, le retraitement prendrait une ligne existante de données créées à la granularité de l'événement de production et de modifier la granularité de minutes, ce qui élimine redondant (fin de l'événement, de l'heure) colonnes en le faisant. Il suppose un taux de production constant et divise la sortie par la différence en minutes plus une pour remplir la colonne Sortie de la nouvelle table.

Je sais que cela peut être fait dans le code ... mais peut-il être fait entièrement dans une instruction d'insertion MySQL (ou autrement entièrement dans MySQL)? Je pense à un INSERT ... DANS la construction mais continue à rester coincé. Une complexité supplémentaire est qu'il y a des centaines de machines à inclure dans l'opération, donc il y aura plusieurs lignes (une pour chaque machine) pour chaque minute de la journée.

Toutes les idées seraient grandement appréciées. Merci.

Répondre

2

Vous pouvez créer une table contenant une ligne pour chaque minute depuis le début de votre ensemble de données à la fin, et exécuter des jointures contre cette:

select user_id, work_id, machine_id, production_minute, output 
from prod_event p 
join prod_minute m on p.start <= m.production_minute and m.production_minute <= p.end; 

Peupler la table prod_minute peut être amusant:

create table counter (i int not null auto_increment primary key); 
insert into counter values (0); 
insert into counter select NULL from counter; 
# ... repeat until your counter table contains enough minutes 

create table prod_minute (production_minute datetime not null primary key); 
insert into prod_minute select date_add('2000-01-01', interval i minute) from counter; 
+0

Merci Martin! Cette approche fonctionnerait parfaitement pour une seule machine. Une complexité supplémentaire est que nous rapportons sur 219 machines, dont un certain nombre entre 0 et 219 peut fonctionner simultanément. Par conséquent, la colonne production_minute peut avoir la même valeur entre 1 et 219 fois, en fonction du nombre de machines s'exécutant dans cette minute. Nous pourrions ajouter une autre colonne comme PK afin de rendre non-unique production_minute, mais comment pourrions-nous répéter le même horodatage pour production_minute un nombre variable de fois basé sur le nombre de machines en cours d'exécution dans cette minute? – lighthouse65

+0

Si toutes vos données sont dans la seule table prod_event, la jointure unique doit vous couvrir pour tous les id_utilisateur, id_travail, id_machine et sortie. Essayez-le sur un petit extrait - ça devrait juste marcher. – Martin

+0

Je vois ... vais l'essayer et le poster ... merci encore. – lighthouse65

Questions connexes