计算开始和结束时间之间每小时的数字

时间:2015-10-30 12:23:02

标签: sql-server excel date datetime

我有一个考勤管理系统,记录每次出勤的开始和结束时间。我可以通过将开始时间从结束时间开始来轻松计算停留时间。

数据的一个例子如下: -

VisitUID          | AttendeeID   | Start_time              | End_time
0  -----          123  -----     01/01/2015 09:15  -----   01/01/2015 17:15
1  -----          456  -----     01/01/2015 10:45  -----   01/01/2015 16:30
2  -----          753  -----     01/01/2015 08:05  -----   01/01/2015 17:45
3  -----          975  -----     01/01/2015 07:15  -----   01/01/2015 15:05
4  -----          864  -----     01/01/2015 15:55  -----   01/01/2015 16:25
5  -----          246  -----     01/01/2015 16:00  -----   01/01/2015 17:35
6  -----          357  -----     01/01/2015 11:10  -----   01/01/2015 14:55

所以计算会是这样的(请原谅我,如果我错了!): -

07 - 1
08 - 2
09 - 3
10 - 4
11 - 5
12 - 5
13 - 5
14 - 5
15 - 5
16 - 5
17 - 3

我想弄清楚的是,如何计算每小时有多少人在现场了解网站上的数字?

系统是SQL,开始和结束都是日期时间值,所以在SQL或甚至Excel中计算它的方法会很棒。

5 个答案:

答案 0 :(得分:2)

Excel中。另一个downvote :)

enter image description here

在F3中复制的公式是:

=--AND(HOUR($C3)<G$2,HOUR($D3)>=F$2)  

F1中的公式并复制到:

 =SUM(F3:F1000)

答案 1 :(得分:1)

如果您的数据已经存在于SQL Server数据库中,则无需将它们输出到Excel中。它可以通过几行SQL完成。如果您更喜欢Excel,那么您可以在上方或下方选择一些不错的选项。

首先需要一张包含所有可能时间的表:values(7), (8), ... 然后,当此表中的小时位于开始日期和结束日期之间时,它可以与您的数据连接。

您的数据:

declare @date table(VisitUID int, AttendeeID int, Start_time datetime, End_time datetime)
Insert Into @date(VisitUID, AttendeeID, Start_time, End_time) values
    (0, 123, '01/01/2015 09:15', '01/01/2015 17:15')
    , (1, 456, '01/01/2015 10:45', '01/01/2015 16:30')
    , (2, 753, '01/01/2015 08:05', '01/01/2015 17:45')
    , (3, 975, '01/01/2015 07:15', '01/01/2015 15:05')
    , (4, 864, '01/01/2015 15:55', '01/01/2015 16:25')
    , (5, 246, '01/01/2015 16:00', '01/01/2015 17:35')
    , (6, 357, '01/01/2015 11:10', '01/01/2015 14:55')

<强>查询:

Select h.n, COUNT(*)
From (values(7), (8), (9), (10), (11), (12), (13), (14), (15), (16), (17), (18)) as h(n)
Inner Join @date d on 
    h.n >= DATEPART(hour, d.Start_time) 
    and  h.n <= DATEPART(hour, d.End_time)+1
Group by h.n

如果您需要0到7或18到0之间的数据,只需将它们添加到列表中:values(6), (7), (8)...(18)...

您的计算似乎是正确的。我有相同的输出。

<强>输出:

Hour    Count
7       1
8       2
9       3
10      4
11      5
12      5
13      5
14      5
15      5
16      5
17      3

答案 2 :(得分:1)

您可以在以下内容中使用UNPIVOT

<强> QUERY

;with cte as
(
select   DATEPART(hh,Start_time) StartTime
       , DATEPART(hh,End_time) EndTime
       , CASE WHEN 7 BETWEEN DATEPART(hh,Start_time) AND DATEPART(hh,End_time) THEN 1  ELSE 0 END AS [7]
       , CASE WHEN 8 BETWEEN DATEPART(hh,Start_time) AND DATEPART(hh,End_time) THEN 1  ELSE 0 END AS [8]
       , CASE WHEN 9 BETWEEN DATEPART(hh,Start_time) AND DATEPART(hh,End_time) THEN 1  ELSE 0 END AS [9]
       , CASE WHEN 10 BETWEEN DATEPART(hh,Start_time) AND DATEPART(hh,End_time) THEN 1 ELSE 0 END AS [10]
       , CASE WHEN 11 BETWEEN DATEPART(hh,Start_time) AND DATEPART(hh,End_time) THEN 1 ELSE 0 END AS [11]
       , CASE WHEN 12 BETWEEN DATEPART(hh,Start_time) AND DATEPART(hh,End_time) THEN 1 ELSE 0 END AS [12]
       , CASE WHEN 13 BETWEEN DATEPART(hh,Start_time) AND DATEPART(hh,End_time) THEN 1 ELSE 0 END AS [13]
       , CASE WHEN 14 BETWEEN DATEPART(hh,Start_time) AND DATEPART(hh,End_time) THEN 1 ELSE 0 END AS [14]
       , CASE WHEN 15 BETWEEN DATEPART(hh,Start_time) AND DATEPART(hh,End_time) THEN 1 ELSE 0 END AS [15]
       , CASE WHEN 16 BETWEEN DATEPART(hh,Start_time) AND DATEPART(hh,End_time) THEN 1 ELSE 0 END AS [16]
       , CASE WHEN 17 BETWEEN DATEPART(hh,Start_time) AND DATEPART(hh,End_time) THEN 1 ELSE 0 END AS [17]
from #test
)
select StartTime1 StartTime, sum(Cnt) Counter
from(
select StartTime,[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17]
from cte
) p
UNPIVOT
(
    Cnt FOR StartTime1 IN ([7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17])
)AS unpvt
group by StartTime1
order by CAST(StartTIme1 AS INT)

示例数据

create table #test
(
VisitUID   INT,
AttendeeID INT,
Start_time DATETIME,
End_time   DATETIME,
)
insert into #test values
(0, 123,'01/01/2015 09:15','01/01/2015 17:15'),
(1, 456,'01/01/2015 10:45','01/01/2015 16:30'),
(2, 753,'01/01/2015 08:05','01/01/2015 17:45'),
(3, 975,'01/01/2015 07:15','01/01/2015 15:05'),
(4, 864,'01/01/2015 15:55','01/01/2015 16:25'),
(5, 246,'01/01/2015 16:00','01/01/2015 17:35'),
(6, 357,'01/01/2015 11:10','01/01/2015 14:55')

<强>输出

StartTime   Counter
7           1
8           2
9           3
10          4
11          5
12          5
13          5
14          5
15          5
16          5
17          3

答案 3 :(得分:1)

enter image description here

在此图片中,以下单元格包含以下公式/常量...

F3 ...... 01.01.2015 00:00:00

G3 ... =F3+TIME(1;0;0) ...将此权利复制到AC3

F4 ... =IF(AND(F$3>=$D4;F$3<$E4);1;0) ...向右/向下复制,直到AC10

F12 ...... =SUM(F4:F11) ...将此权利复制到AC12

这里的关键是检查用户登录期限是否包含&#39;您想要测试的时间点(例如,test_time&gt; = start_time和test_time&lt; end_time)...从而您可以获得哲学思考&#39; s&gt; =和&lt;或者&gt;和&lt; =

现在......如果你想要一个日常活动曲线而没有在标题中硬编码日期,你可以只在标题中有时间并将其与用户登录/输出日期的时间部分进行比较(如在=日期中) -INT(日期)......)

答案 4 :(得分:1)

  

......甚至Excel都会很棒。

假设您的数据位于A:D列中,请选择11个连续垂直单元格并将以下内容粘贴到公式栏中并使用CONTROL-ENTER确认:

=SUMPRODUCT((ROWS($1:1)+6>=HOUR(C$2:C$99))*(ROWS($1:1)+6<=HOUR(D$2:D$99)))

注意:如果出勤数据超出第99行,则适当增加公式中的99s。