4

我正在完成我的第一个 asp.net 网络应用程序,但遇到了一个难题。该网络应用程序旨在测试全国各地的网络设备并记录响应时间。Windows 服务会定期检查这些设备,通常每 1-10 分钟一次。然后将每次检查的结果记录在采用这种设计的 SQL Server 表中。(当设备关闭时,ResponseTime 为 NULL。)

CREATE TABLE [dbo].[DeviceStatuses] (

[DeviceStatusID] INT      IDENTITY (1, 1) NOT NULL,
[DeviceID]       INT      NOT NULL,
[StatusTime]     DATETIME NULL,
[ResponseTime]   INT      NULL,
CONSTRAINT [PK_DeviceStatuses] PRIMARY KEY CLUSTERED ([DeviceStatusID] ASC),
CONSTRAINT [FK_DeviceStatuses_Devices] FOREIGN KEY ([DeviceID]) REFERENCES [dbo].[Devices] ([DeviceID])
);

该服务已经运行了几个月,设备数量最少,表有大约 500,000 行。客户希望能够访问每台设备的 3 个月滚动停机时间摘要。类似于以下内容:

停机时间:
12/11/2012 3:20 PM - 3:42 PM
12/20/2012 1:00 AM - 9:00 AM

据我所知,我需要获取每个 NULL ResponseTimes 块的开始和结束的 StatusTime,当然对于特定的 DeviceID。我在 Google 和 StackOverflow 上进行了多次搜索,但没有找到任何类似于我正在尝试做的事情。(也许我没有使用正确的搜索词。)我的兄弟,一个更有经验的程序员,建议我可以在 SQL Server 中使用 CURSOR,尽管他承认 CURSOR 性能很糟糕,需要一个计划任务。有什么建议吗?

4

1 回答 1

1
declare  @DeviceStatuses table(

[DeviceStatusID] INT      IDENTITY (1, 1) NOT NULL,
[DeviceID]       INT      NOT NULL,
[StatusTime]     DATETIME NULL,
[ResponseTime]   INT      NULL)


Insert into @DeviceStatuses([DeviceID],[StatusTime],[ResponseTime])
Values
(1,'20120101 10:10',2),(1,'20120101 10:12',NULL),(1,'20120101 10:14',2),
(1,'20120102 10:10',2),(1,'20120102 10:12',NULL),(1,'20120102 10:14',2),
(2,'20120101 10:10',2),(2,'20120101 10:12',NULL),(2,'20120101 10:14',2),
(2,'20120101 10:19',2),(2,'20120101 10:20',NULL),(2,'20120101 10:21',NULL),(2,'20120101 10:22',2),
(2,'20120102 10:10',2),(2,'20120102 10:12',NULL),(2,'20120102 10:14',2);

Select [DeviceID],MIN([StatusTime]) as StartDown,MAX([StatusTime]) as EndDown
from
(
Select [DeviceID],[StatusTime]
,(Select MAX([StatusTime]) from @DeviceStatuses s2 where s2.DeviceID=s1.DeviceID and s2.StatusTime<s1.StatusTime and s2.ResponseTime is not null) as gr
from @DeviceStatuses s1
where s1.ResponseTime is null
)a
Group by [DeviceID],gr
order by [DeviceID],gr
于 2013-01-04T10:10:19.720 回答