OK,我也建議使用的功能,因爲這也許慢了很多大表上也更容易,更簡單的代碼。
但這裏是沒有功能的另一個解決方案:
-- the day you're interested in:
declare @day datetime
set @day = '2012-01-20'
-- sample data
declare @moves table (id int, tin datetime, tout datetime)
insert into @moves values
(1, '2012-01-20 06:30:00', '2012-01-20 15:45:00'),
(2, '2012-01-20 13:05:00', '2012-01-20 19:45:00'),
(3, '2012-01-20 10:10:00', '2012-01-20 10:50:00'),
(4, '2012-01-20 19:35:00', '2012-01-20 21:00:00')
-- a helper table with hours
declare @i int
declare @hours table (h int, f datetime, t datetime)
set @i = 0
while @i < 24
begin
insert into @hours values(@i, dateadd(hour, @i, @day), dateadd(hour, @i + 1, @day))
set @i = @i + 1
end
-- here's the code
select h.h,
sum(case sign(datediff(second, h.f, m.tin))
when 1 then
case sign(datediff(second, m.tout, h.t))
when 1 then datediff(minute, m.tin , m.tout)
else datediff(minute, m.tin , h.t)
end
when null then null
else
case sign(datediff(second, m.tout, h.t))
when 1 then datediff(minute, h.f, m.tout)
else datediff(minute, h.f, h.t)
end
end) as minutesWorked,
count(distinct m.id) as peopleWorking
from @hours h inner join @moves m
-- on h.f >= m.tin and h.t <= m.tout
on h.f <= m.tout and h.t >= m.tin
group by h.h
order by h.h
這會給你下面的結果:
h minutesWorked peopleWorking
----------- ------------- -------------
6 30 1
7 60 1
8 60 1
9 60 1
10 100 2
11 60 1
12 60 1
13 115 2
14 120 2
15 105 2
16 60 1
17 60 1
18 60 1
19 70 2
20 60 1
21 0 1
是否有日期,或只是時間? IN和OUT可以跨越日期邊界嗎? I.E. IN在11:30 PM,OUT在2:30 AM? – Sparky 2012-01-18 17:00:34
他們會交叉,但爲了簡單起見,讓我們假設他們現在不會。在我得到如何做到這一點之後,我可以照顧邊緣案例。 – 2012-01-18 18:02:05