我正在完成我的第一个asp.net网络应用程序,我遇到了一个棘手的问题。该Web应用程序旨在测试全国各地的网络设备并记录响应时间。 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性能很差并且需要预定的任务。有什么建议吗?
答案 0 :(得分: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