2015-10-30 176 views
2

我有一個考勤管理系統,記錄每次考勤的開始時間和結束時間。我可以通過從結束時間開始計算開始時間來輕鬆計算停留時間。計算開始時間和結束時間之間的每小時數

的數據的一個例子是這樣的: -

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中計算這個值的方法將會非常驚人。

+2

你介意添加你到目前爲止嘗試過的查詢嗎? – Wanderer

+0

SUM()a CASE表達式,如果該人員在相關小時內返回1,則返回1;如果不是,則爲0。 –

+0

預期結果的第一列是什麼?如果那是一天中的小時,它與樣本數據不匹配。如果你需要跨越幾天,你還需要一個日期。 –

回答

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 
+0

感謝您的回答Julien。這裏有一些非常好的建議 – stevenk

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 
+0

誰和爲什麼downvoted沒有留下評論? –

+0

Q也一直在? – pnuts

+0

@pnuts MikeD ...有人玩得很開心... –

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

這裏的實質是檢查用戶登錄時段是否包含您想要測試的時間點(例如,test_time> = start_time和test_time < end_time)...從而您可以獲取哲學信息並且> =和<或>和< =

現在...如果你想要一個日常活動曲線w如果沒有對標題中的日期進行硬編碼,則只能在標題中將時間與用戶登錄/日期的時間部分進行比較(如in = date-INT(date)...)

+0

我正要提出一些非常相似的東西 - 但你也提供了一張圖表!但我認爲應該有六個連續的'5's,而不是三個,然後是兩個'4's。 – pnuts

+0

你的圖表從8或9變爲18.不應該是從7到17,因爲它從7:15開始爲uid 3?它似乎滑了1小時。 –

+0

圖表是一個獎金,而是...但我想如果我正在做這樣的事情我希望它呈現在幾何...爲兩個4的讓我檢查 – MikeD

2

Excel 。對於另一downvote :)

enter image description here

在F3的公式跨,下複製到西裝:

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

在F1的公式和整個複製的是:

=SUM(F3:F1000) 
+1

一個非常優雅的解決方案! – MikeD

+0

@MikeD謝謝! (已經有好幾次了,OP似乎忽略了我的優惠。)但是我仍然喜歡你提供的可視化。 PS你是否擊中了錯誤的箭頭 - 整個這篇文章的投票似乎是相反的:) – pnuts

+1

nope ...我upvoted你的答案,因爲我真的很喜歡提取小時只是爲了獲得(平均)每日檔案的想法。 – MikeD

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行,然後適當增加公式中的99。

+0

@stevenk您是否能夠完成這項工作? –

+0

十一而不是十? – pnuts

+0

工作了一個魅力,感謝Excel英雄。這可能是所有建議的最簡單的解決方案,但我會選擇其中一個基於SQL的解決方案作爲回答,因爲這樣可以節省我首先將數據導入到excel中。 – stevenk

相關問題