计算两个记录之间的差异(时间),保留结果中的最后一个记录

时间:2011-11-04 21:31:24

标签: sql-server-2008 tsql

我有一个包含TagName,TimeStamp和机器状态的过程数据的表,1 =正在运行,0 =未运行。原始数据可能如下所示:

Bss105_AUTO 2011-11-03 17:00:00.0000000 1
Bss105_AUTO 2011-11-03 22:32:49.5520000 1
Bss105_AUTO 2011-11-03 22:36:52.3200000 1
Bss105_AUTO 2011-11-04 08:15:28.6460000 0
Bss105_AUTO 2011-11-04 08:17:42.6520000 1
Bss105_AUTO 2011-11-04 11:49:42.3780000 1

我想要实现的是使用此查询计算机器的总运行时间:

 WITH    rows AS
        (
        SELECT *, ROW_NUMBER() OVER (ORDER BY DateTime) AS RowNumber
        FROM   History where TagName='Bss105_AUTO' 
                AND DateTime >= '2011-11-03 17:00:00.000' 
                AND DateTime <= '2011-11-04 17:00:00.000'
                AND wwRetrievalMode = 'Delta'
                AND wwVersion = 'Original'
                AND OPCQuality = 192
        ) 
    SELECT  mc.RowNumber, mc.DateTime, mc.TagName, mc.Value as MachineStatus, DATEDIFF(second, mc.DateTime, mp.DateTime) GrindingMachineRuntimeInSeconds
    FROM    rows mc 
    JOIN    rows mp 
    ON      mc.RowNumber = mp.RowNumber - 1 
    where mc.Value <> 0

我不想包括机器未运行的计算停机时间(状态0 =未运行)。没问题,我可以通过从结果中排除这些记录来实现这一点(最后一列包含记录之间的秒数)。

1   2011-11-03 17:00:00.0000000 Bss105_AUTO 1   19969
2   2011-11-03 22:32:49.5520000 Bss105_AUTO 1   243
3   2011-11-03 22:36:52.3200000 Bss105_AUTO 1   34716
5   2011-11-04 08:17:42.6520000 Bss105_AUTO 1   12720

我的问题是我还需要使用此时间戳存储的最后一条记录:2011-11-04 11:49:42.3780000

仅当此时机器状态等于1(=正在运行)时才会出现这种情况,因为我需要知道它是否正在运行,以便能够计算从最后存储的记录到结束的运行时间。查询间隔!!该记录的最后一列必须为空!

那里有没有专家可以帮我解决这个问题?

亲切的问候!

1 个答案:

答案 0 :(得分:1)

CREATE TABLE [dbo].[History]
(
    [TagName]           CHAR(11)    NOT NULL,
    [DateTime]          DATETIME2   NOT NULL,
    [MachineStatus]     BIT         NOT NULL
)
GO

INSERT  [dbo].[History]
VALUES  ('Bss105_AUTO', '2011-11-03 17:00:00.0000000', 1),
        ('Bss105_AUTO', '2011-11-03 22:32:49.5520000', 1),
        ('Bss105_AUTO', '2011-11-03 22:36:52.3200000', 1),
        ('Bss105_AUTO', '2011-11-04 08:15:28.6460000', 0),
        ('Bss105_AUTO', '2011-11-04 08:17:42.6520000', 1),
        ('Bss105_AUTO', '2011-11-04 11:49:42.3780000', 1)
GO

;WITH [cteRows] AS
(
    SELECT  [TagName],
            [DateTime],
            [MachineStatus],
            ROW_NUMBER() OVER (ORDER BY [DateTime]) AS [RowNumber]
    FROM [dbo].[History]
    WHERE [TagName] = 'Bss105_AUTO' 
    AND [DateTime] >= '2011-11-03 17:00:00.000' 
    AND [DateTime] <= '2011-11-04 17:00:00.000'
) 
SELECT  mc.[RowNumber],
        mc.[DateTime],
        mc.[TagName],
        mc.[MachineStatus],
        DATEDIFF(SECOND, mc.[DateTime], ISNULL(mp.[DateTime], mc.[DateTime])) AS [GrindingMachineRuntimeInSeconds]
FROM [cteRows] mc 
LEFT JOIN [cteRows] mp 
    ON mc.[RowNumber] = mp.[RowNumber] - 1 
WHERE mc.[MachineStatus] <> 0