时间差和开关量

时间:2017-10-17 13:13:23

标签: sql entity-framework linq

我有一个物联网产品的应用程序,这些产品会间隔或错误地报告给服务器。现在我想创建一份关于产品稳定性的报告,我有以下数据。

<%@ Register TagPrefix="dnn" TagName="LOGIN" Src="~/Admin/Skins/Login.ascx" %>

我想知道产品有多长时间是InError,以及上面的例子应该多久返回一次 2次,价值02:30:00

如何使用EF / linq或必要时使用SQL?

2 个答案:

答案 0 :(得分:0)

我不是EF或linq的专家,但如果您使用的是MySql,则可以使用一个类似的查询(使用临时变量)来完成。这更像是一个伪代码,你需要稍微调整它,特别是日期计算,但它显示了这个想法。

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

在SQL Server中,您可以通过ReportTime使用LAG函数执行类似的操作: 像

这样的东西
 ReportTime - LAG(ReportTime) OVER (ORDER BY ReportTime) errorDuration 

或者你可以使用rank()和临时表:

 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

这个想法是让前一个时间和每一行都有自上次报告以来的持续时间。之后,当你有这个&#34;查看&#34;您只需通过InError对持续时间和组进行求和,即可获得错误状态和正常状态的持续时间。大多数数据库允许您这样做,但它通常涉及特定的功能

答案 1 :(得分:0)

试试这个solution。在第一个位置Insert start项而非inError状态进入data非常重要,因为第一个inError行也可以在整个行集中排在第一位在这种情况下,您应该有前一行,以执行减法和有效的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();