很抱歉再次提出基于出勤的问题,但是这里的其他解决方案似乎都不适合我。
我需要每天获取每位员工的“先进先出”列表。表格看起来像这样:
$result = Master::where(function ($query) use ($request) {
if ($request->filter == true) {
$query->where('user_id', Auth::user()->id);
}
// other conditions here
if (!empty($request->area_from) && !empty($request->area_to)) {
$query->whereHas('one', function ($query) use ($request) {
$query->whereBetween('area', [$request->area_from, $request->area_to]);
});
$query->orWhereHas('two', function ($query) use ($request) {
$query->whereBetween('area', [$request->area_from, $request->area_to]);
});
}
// other conditions here
})->with(['one', 'two'])->paginate($request->item);
我需要这样的结果:
id date_time access emp_id
1 2016-01-01T09:00:00Z In 00101
2 2016-01-01T09:10:00Z In 00302
3 2016-01-01T13:10:00Z Out 00101
4 2016-01-01T13:05:00Z Out 00302
5 2016-01-01T14:00:00Z In 00302
6 2016-01-01T14:10:00Z In 00101
7 2016-01-01T17:00:00Z Out 00101
8 2016-01-01T17:10:00Z Out 00302
9 2016-01-02T09:05:00Z In 00101
10 2016-01-02T09:10:00Z In 00302
11 2016-01-02T12:05:00Z Out 00101
12 2016-01-02T12:35:00Z Out 00302
13 2016-01-02T13:40:00Z In 00302
14 2016-01-02T17:15:00Z Out 00302
15 2016-01-03T08:50:00Z In 00302
16 2016-01-03T17:10:00Z Out 00101
因此,在第二天,我知道有1名员工离开去吃午餐,并且没有回来。在第3天的时候,一些员工一直在忙活,需要对通行证使用情况进行授课。
我的问题是,要获得最小/最大时间不是那么简单,因为它们基于访问类型。分别获取进入或退出时间并不困难,但是由于MYSQL中缺少完整的外部联接,因此将它们组合到1个结果表中是很棘手的。
workday emp_id entry_time entry_time
2016-01-01 00101 2016-01-01T09:00:00Z 2016-01-01T17:00:00Z
2016-01-01 00302 2016-01-01T09:10:00Z 2016-01-01T17:10:00Z
2016-01-02 00101 2016-01-02T09:05:00Z 2016-01-02T12:05:00Z
2016-01-02 00302 2016-01-02T09:10:00Z 2016-01-02T17:15:00Z
2016-01-03 00302 2016-01-03T08:50:00Z 0
2016-01-03 00101 0 2016-01-03T17:10:00Z
请原谅,如果我也没有尝试在这些陈述中尝试左右联接的尝试。
我所能管理的最好是将进入和退出时间放在单独的行上,这并不理想。
select cast(date_time as date) as workday, emp_id, min(date_time) as entry_time from attendance where access = 'In' group by date(date_time), emp_id order by workday;
select cast(date_time as date) as workday, emp_id, max(date_time) as exit_time from attendance where access = 'Out' group by date(date_time), emp_id order by workday;
产生:
select cast(date_time as date) as workday, emp_id, IF (access = 'In', MIN(date_time), 0) as entry_time, IF (access = 'Out', MAX(date_time), 0) as exit_time from attendance group by date(date_time), emp_id, access order by workday;
What I have tried on SQL Fiddle
有什么我想念的吗?有没有更好的做事方法?
感谢您的协助,在此先感谢您。
答案 0 :(得分:0)
我认为您需要再做一个group by
。见下文:
select p.workday, p.emp_id, max(p.time_in), max(p.time_out)
from (
select cast(date_time as date) as workday, emp_id,
min(case when (access='In') then date_time else 0 end) as time_in,
max(case when (access='Out') then date_time else 0 end) as time_out
from attendance
group by cast(date_time as date), emp_id, access
) as p
group by p.workday, p.emp_id
这将产生预期的结果。这是demo