2017-10-10 14 views
-1

MySQLを使用して従業員の生産時間を計算する必要があります。 バイオメトリックでは、それぞれの従業員のINタイムとアウトタイムを取得します。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またはdate(log_date)に変更がある場合は、 の値がリセットされる1つのrow_numberが生成されます。

サブクエリout_timing:

このサブクエリは、ユーザーの特定の日にすべてのアウトの時間を計算するのに使用されます。 emp_codeまたはdate(log_date)に変更がある場合は、 の値がリセットされる1つのrow_numberが生成されます。

結果への結合: emp_code、date(log_date)およびrow_numberに基づいてこれらの2つのサブクエリを結合します。

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クエリはTotal and Productive Hours –

0

ここに1つのアイデアがあります。私は、従業員だけで任意の日に二回入る

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

2度以上テストしましたか? –

+0

@FahadAnjum私は;-)する必要はありません - しかし、それはすべての 'の'のための(同じ日) 'アウト' – Strawberry

関連する問題