2017-10-10 108 views
-1

我有一個要求來計算使用MySQL的員工的生產小時數。 Bio-Metric將捕獲相應員工的IN Time和Out Time。MySQL:員工生產時間計算

emp_device_attendance表中的數據完全相同的樣子如下:

**log_date   device_id emp_code device_direction** 
2017-09-25 19:34:14 108   400148   out 
2017-09-25 14:07:13 106   400148   in 
2017-09-25 13:25:10 108   400148   out 
2017-09-25 10:45:03 106   400148   in 

從上面的表格,我需要排除的時候,他用了「走出去」代表的報告。意味着我們需要呈現他在辦公室裏有多少時間。

輸出應該看起來象下面這樣:

emp_id date   in_time out_time total_hrs productive_hrs 
400148 2017-09-25 10:45:03 19:34:14 08:49:11 08:07:41 

有人可以請幫我在MySQL中這樣做。

+1

一個員工在任何一天只能進入兩次? – Strawberry

+0

他可以有多個輸入和輸出的條目,每個輸入和輸出都有保存的記錄 –

+0

然後這個例子並沒有充分反映真實情況。 – Strawberry

回答

0

讓我解釋查詢。

子查詢in_timing:

此子查詢被用來計算在用戶的時間和上特定日期的所有。如果emp_code或日期(log_date)發生更改,將生成一個row_number,其 值將被重置。

子查詢out_timing:

此子查詢被用來計算出所有在特定日期的用戶和時間。如果emp_code或日期(log_date)發生更改,將生成一個row_number,其 值將被重置。

加入到結果中: 現在基於emp_code,date(log_date)和row_number加入這兩個子查詢。

現在使用timediff和sec_to_time和time_to_sec可以得到您需要的結果。

我希望這會幫助你。

create table emp_device_attendance (
    log_date timestamp, 
    device_id int, 
    emp_code varchar(20), 
    device_direction varchar(5) 
); 

insert into emp_device_attendance values('2017-09-25 19:34:14',108,'400148','out'); 
insert into emp_device_attendance values('2017-09-25 14:07:13',106,'400148','in'); 
insert into emp_device_attendance values('2017-09-25 13:25:10',108,'400148','out'); 
insert into emp_device_attendance values('2017-09-25 10:45:03',106,'400148','in'); 

set @inNumber = 0; 
set @inEmpCode = ''; 
set @inLogDate = ''; 
set @outNumber = 0; 
set @outEmpCode = ''; 
set @outLogDate = ''; 

select abc.emp_code,abc.date1,min(in_time) ,max(out_time), 
timediff(max(out_time), min(in_time)) total_hrs, 
sec_to_time(sum(productive_hrs)) productive_hrs 
from ( 
select in_timing.emp_code,in_timing.date1, 
min(in_timing.log_date) as in_time, 
max(out_timing.log_date) as out_time, 
time_to_sec(timediff(max(out_timing.log_date), min(in_timing.log_date))) productive_hrs 
from 
(select device_id,emp_code,device_direction, date(log_date) as date1, log_date , 
    if(@inEmpCode = emp_code and @inLogDate = date(log_date) , @inNumber := @inNumber + 1 ,@inNumber := 1) row_number, 
    @inEmpCode := emp_code ,@inLogDate := date(log_date) 

    from emp_device_attendance 
    where 
    device_direction = 'in' 
    order by log_date, emp_code 
) in_timing join 
(select device_id,emp_code,device_direction, date(log_date) as date1, log_date , 
    if(@outEmpCode = emp_code and @outLogDate = date(log_date) , @outNumber := @outNumber + 1 ,@outNumber := 1) row_number, 
    @outEmpCode := emp_code ,@outLogDate := date(log_date) 

    from emp_device_attendance 
    where 
    device_direction = 'out' 
    order by log_date, emp_code) out_timing on in_timing.row_number = out_timing.row_number 
and in_timing.emp_code = out_timing.emp_code 
and in_timing.date1 = out_timing.date1 

group by in_timing.emp_code,in_timing.date1 
,in_timing.row_number) abc 
group by abc.emp_code,abc.date1 
+0

好悲痛,這是很多查詢:-( – Strawberry

+0

@Strawberry我認爲是這樣,但它處理所有的測試用例,因爲它有這麼多的查詢。 –

+0

@FahadAnjum該查詢返回相同的總和生產小時,這將不是這樣,當我們在同一天有多個進出口時,生產時間會有所不同 –

0

這裏有一個想法。我應該說,這對你的數據集有一定的假設,可能會也可能不會,但它應該給你這個想法...

SELECT emp_code 
    , DATE(log_date) dt 
    , SEC_TO_TIME(SUM(subtotal)) t 
    FROM 
    (SELECT x.emp_code 
      , x.log_date 
      ,TIME_TO_SEC(x.log_date)-TIME_TO_SEC(MAX(y.log_date)) subtotal 
     FROM emp_device_attendance x 
     JOIN emp_device_attendance y 
      ON y.emp_code = x.emp_code 
      AND y.log_date < x.log_date 
      AND y.device_direction = 'in' 
     WHERE x.device_direction = 'out' 
     GROUP 
      BY x.emp_code,x.log_date 
    ) a 
GROUP 
    BY emp_code,dt; 
+0

您是否測試過兩次以上? –

+0

@FahadAnjum我不需要;-) - 但它確實假設每個'in'都有一個(同一天)「out」 – Strawberry