2017-10-17 12 views
1

J'ai une application pour l'Internet des objets produits ces produits rapportent dans un intervalle ou sur erreur au serveur. maintenant je veux créer un rapport sur la stabilité des produits et j'ai les données suivantes.La somme des différences de temps et la quantité de commutateurs

ID ReportTime (DateTime) InError 
1 2017-17-10 03:00:00  False 
1 2017-17-10 03:30:00  True 
1 2017-17-10 04:00:00  False 
1 2017-17-10 05:00:00  False 
1 2017-17-10 06:00:00  True 
1 2017-17-10 07:00:00  True 
1 2017-17-10 08:00:00  False 

Je veux savoir combien de temps le produit a été InError et à quelle fréquence si l'exemple ci-dessus, il devrait revenir 2 fois avec une valeur de 02:30:00

Comment puis-je faire en utilisant EF/linq ou, si nécessaire, SQL?

+0

Il semble que le produit ait été InError 3 fois. Comment venez-vous à 2 fois? –

+0

quelle est la base de données que vous avez si vous envisagez de le faire en SQL? –

+0

base de données est MSSQL, le produit est en erreur 2 fois parce que seulement à chaque changement entre un enregistrement faux et vrai, il devrait compter un nouvel état. –

Répondre

0

Je ne suis pas un expert en EF ou linq mais si vous utilisez un MySql par exemple, vous pouvez le faire avec une requête comme ça (en utilisant une variable temporaire). Cela ressemble plus à un pseudo code que vous avez besoin de modifier avec un peu spécialement pour le calcul de la date, mais il montre l'idée.

SELECT InError,sum(errorDuration) from (
    SELECT ID, 
      ReportTime , 
      InError , 
      @prevReportTime :=ReportTime, 
      [email protected] as errorDuration 
    FROM thetable 
    JOIN (SELECT @prevReportTime := (SELECT min(ReportTime) from the table)) t 
    ORDER BY ReportTime 
) group by InError 

Dans SQL Server, vous pouvez faire une chose similaire en utilisant la fonction LAG sur par ReportTime: Quelque chose comme

ReportTime - LAG(ReportTime) OVER (ORDER BY ReportTime) errorDuration 

Ou vous pouvez utiliser le rang() et table temporaire:

select rank() OVER (ORDER BY ReportTime) as 'Rank', value into temp1 from theTable 

select t1.inError, t1.ReportTime- t2.ReportTime as duration from temp1 t1, temp1 t2 
where t1.Rank = t2.Rank - 1 

L'idée est d'obtenir l'heure précédente et pour chaque ligne d'avoir la durée depuis le rapport précédent. Après cela, quand vous avez cette "vue", vous additionnez juste cette durée et groupez par InError pour obtenir la durée de l'état d'erreur et de l'état normal. La plupart des bases de données vous permettent de le faire mais cela implique généralement des fonctions spécifiques

0

Essayez ceci solution. Il est important de Insertstart article ne inError état en data à première position, car la première inError ligne peut aussi être le premier parmi ensemble de lignes et à ce cas, vous devriez avoir rangée précédente pour elle, pour effectuer la soustraction et valide le calcul switches:

var start = DateTime.Today; 
//for example, fetch data for current day 
var data = db.Table.Where(x => x.Datetime >= start && x.Datetime < tomorrow).ToList(); 

data.Insert(0, new Log { InError = false, DateTime = start }); 

var time = new TimeSpan(data.Where(x => x.InError).Sum(x =>    
    (x.DateTime - data[data.IndexOf(x) - 1].DateTime).Ticks 
)); 

var switches = data.Where(x => x.InError && !data[data.IndexOf(x) - 1].InError).Count();