0

If i have a table which has a data column, how can i count the time period in hours between the entries. Assuming that 1 row effectively signifies the state change of the previous row. eg

TableA
Name Status(Int) DateTime (DateTiem2)
Bob In '2012-11-22 00:00:00'
Bob Out '2012-11-23 00:00:00'
Bob In '2012-11-24 00:00:00'
Bob Out '2012-11-25 00:00:00'
Bob In '2012-11-26 00:00:00'
Bob Out '2012-11-26 12:30:00'
Bob Absent '2012-11-27 00:00:00'
Bob In '2012-11-27 01:00:00
Jo In '2012-11-22 00:00:00'
Jo Out '2012-11-23 00:00:00'
Jo In '2012-11-24 00:00:00'
Jo Out '2012-11-25 00:00:00'
Jo In '2012-11-26 00:00:00'
Jo Out '2012-11-26 12:30:00'
Jo Absent '2012-11-27 00:00:00'
Jo In '2012-11-27 01:00:00

Totals Query result from Bob In: 60.5 hrs Bob Out: 59.5 hrs Bob Absent: 1 hr Jo In: 60.5 hrs Jo Out: 59.5 hrs Jo Absent: 1 hr

4

1 回答 1

1

将表连接到自身,以便每一行按顺序匹配下一行。然后按分钟减去日期时间量(因为您需要小数小时)并将分钟除以 60:

declare @T table
(
    name varchar(20),
    [status] int,
    [DateTime] datetime2
)

insert into @T (name, [status], [DateTime])
values ('Bob', 0, '2012-11-22 00:00:00'),
('Bob', 1, '2012-11-23 00:00:00'),
('Bob', 0, '2012-11-24 00:00:00'),
('Bob', 1, '2012-11-25 00:00:00'),
('Bob', 0, '2012-11-26 00:00:00'),
('Bob', 1, '2012-11-26 12:30:00'),
('Bob', 2, '2012-11-27 00:00:00'),
('Bob', 1, '2012-11-27 01:00:00'),
('Jo', 0, '2012-11-22 00:00:00'),
('Jo', 1, '2012-11-23 00:00:00'),
('Jo', 0, '2012-11-24 00:00:00'),
('Jo', 1, '2012-11-25 00:00:00'),
('Jo', 0, '2012-11-26 00:00:00'),
('Jo', 1, '2012-11-26 12:30:00'),
('Jo', 2, '2012-11-27 00:00:00'),
('Jo', 1, '2012-11-27 01:00:00')

;with RowNumbers (RowNum, name, [status], [DateTime])
as
(
    select
        ROW_NUMBER() over (partition by name order by [DateTime]),
        name,
        [status],
        [DateTime]
    from @T
)
select
    T1.name,
    case T1.[status]
        when 0 then 'In'
        when 1 then 'Out'
        when 2 then 'Absent'
      end as [status],
    sum(datediff(MINUTE, T1.[DateTime], T2.[DateTime]) / 60.0) as [hours]
from RowNumbers T1
    inner join RowNumbers T2
        on T1.RowNum = T2.RowNum - 1 -- joins the current row to the next one
        and T1.name = T2.name
group by T1.name, T1.[status]
order by T1.Name, T1.[status]

请注意,上述查询可能不会像在行号上有索引的派生表那样执行。

另外,查询我对名称和状态列的数据类型和实际值做了一些假设。一般方法保持不变。

于 2013-11-01T14:01:28.353 回答