我有一个简单的SQL Express服务器设置并且正在将数据记录到它,我有多台机器(工业机械)我正在监控。每当机器状态发生变化时,我都会创建一个新记录,该记录在以下列中输入数据。运行,空闲和关闭的时间(时间戳),机器名称(文本),状态(1,2或3),以及ReasonCode(1-10)。我需要计算机器在每种状态下的持续时间以及每种状态的原因。我想通过SQL报告提供这个。这是很多工业制造商最近都在寻找的功能,我试图创建一个简单的例子。不幸的是,我不熟悉SQL。我想这可以放在一个存储过程中,每隔n秒运行一次以重新计算。非常感激任何的帮助。
答案 0 :(得分:2)
假设一个名为status
的表包含
MachineName NVarChar(whatever)
Status Int
Reason Int
Time DateTime
然后这个查询应该可以正常工作
Select
st.MachineName,
st.status,
st.reason
st.Time as TimeChanged,
DateDiff(ss, min(dur.Time), st.Time)
From
Status st inner join
Status dur on st.MachineName = dur.MachineName and st.Time <dur.Time
group by
st.MachineName,
St.Status,
st.Time,
st.reason
编辑 - 回答您的评论
select
st.MachineName,
sum(case when status=1 then Duration else 0 end) as RunningTime,
sum(case when status=2 then Duration else 0 end) as IdleTime,
sum(case when status=3 then Duration else 0 end) as DownTime,
From
(Select
st.MachineName,
st.status,
st.reason
st.Time as TimeChanged,
DateDiff(ss, min(dur.Time), st.Time) as Duration
From
Status st inner join
Status dur on st.MachineName = dur.MachineName and st.Time <dur.Time
group by
st.MachineName,
St.Status,
st.Time,
st.reason) as foo
Group by MachineName
这应该获取机器名称和每个状态所用时间的列
答案 1 :(得分:1)
您无需重新计算。您可以按需查询信息。这是一个自包含的例子
DECLARE @Test
Table (
LogTime datetime,
MachineName varchar(100),
Status int ,
ReasonCode int)
INSERT INTO @Test VALUES ('01/01/2011 4:19:11.459' , 'ServerX', 1, 3)
INSERT INTO @Test VALUES ('01/02/2011 3:43:03.652' , 'ServerZ', 0, 4)
INSERT INTO @Test VALUES ('02/04/2011 11:17:51.827' , 'ServerX', 2, 2)
INSERT INTO @Test VALUES ('02/05/2011 4:22:22.205' , 'ServerX', 3, 1)
INSERT INTO @Test VALUES ('01/03/2011 11:42:44.211' , 'ServerZ', 1, 4)
;with TIMEdelta AS (
SELECT
machineName,
t.LogTime,
MIN(nextTime) as nextTime
FROM (
Select
t.MachineName,
t.LogTime,
t1.LogTime nextTime
from @Test t
INNER JOIN @Test t1
ON t.machineName = t1.machineName
AND t.LogTime < t1.LogTime
) t
GROUP BY
machineName,
t.LogTime
)
SELECT
t.MachineName,
t.LogTime,
t.ReasonCode,
t.Status,
DateDiff(DAY, 0, (TIMEdelta.nextTime - TIMEdelta.LogTime) ) Days,
DatePart(HOUR , TIMEdelta.nextTime - TIMEdelta.LogTime ) Hour,
DatePart(MINUTE, TIMEdelta.nextTime - TIMEdelta.LogTime ) MInute
FROM
@Test t
LEFT JOIN TIMEdelta
ON t.LogTime = timedelta.logtime
and t.MachineName = TIMEdelta.MachineName
此输出
MachineName LogTime ReasonCode Status Days Hours Minutes
----------- ----------------------- ----------- ----------- ----------- ----------- -----------
ServerX 2011-01-01 04:19:11.460 3 1 34 6 58
ServerZ 2011-01-02 03:43:03.653 4 0 1 7 59
ServerX 2011-02-04 11:17:51.827 2 2 0 17 4
ServerX 2011-02-05 04:22:22.207 1 3 NULL NULL NULL
ServerZ 2011-01-03 11:42:44.210 4 1 NULL NULL NULL
您可以修改输出以显示当前时间 - 当前状态行的日志时间而不是Null
更新对于枢轴的聚合,您可以使用PIVOT
SELECT
MachineName,
[0] as Started,
[1] as Stopped,
[2] as Paused,
[3] as Foo
FROM
(
SELECT
t.MachineName,
t.status,
cast(TimeDelta.nextTime - t.LogTime as DECIMAL(18,10)) duration
FROM
@Test t
LEFT JOIN TIMEdelta
ON t.LogTime = timedelta.logtime
and t.MachineName = TIMEdelta.MachineName
) source
PIVOT
(
SUM(duration)
FOR status IN ([0], [1], [2], [3])
) AS PivotTable;
哪个有输出
MachineName Started Stopped Paused Foo
----------- ------------ -------------- ------------ ------------
ServerX NULL 34.2907449846 0.7114627315 1.0000000000
ServerZ 1.3331082948 NULL NULL ULL
更新超过月份的已用日期和更新的天数计算