我在MySQL中有一个表如下:
+----+--------+------------------+------+
| id | userid | fecha_ingreso | tipo |
+----+--------+------------------+------+
| 1 | 1 | 2015-06-08 20:00 | 1 |
| 3 | 1 | 2015-06-09 05:00 | 2 |
| 18 | 2 | 2015-06-09 23:30 | 1 |
| 19 | 2 | 2015-06-10 05:00 | 2 |
| 20 | 2 | 2015-06-10 06:00 | 1 |
| 21 | 2 | 2015-06-10 09:00 | 2 |
| 22 | 1 | 2015-06-09 23:30 | 1 |
| 23 | 1 | 2015-06-10 05:00 | 2 |
| 24 | 1 | 2015-06-10 06:00 | 1 |
| 25 | 1 | 2015-06-10 09:00 | 2 |
+----+--------+------------------+------+
10 rows in set
此表包含进入工作和离开工作的每个用户(userid
)的信息(fecha_ingreso
)。例如,userid=1
已在tipo=1
输入('2015-06-08 20:00'
),而他将工作留在'2015-06-09 05:00'
。
然后我输入了userid=2
tipo=1
来'2015-06-09 23:30'
(夜间)工作,他离开(tipo=2
)工作,在{{1}吃早餐他再次进入'2015-06-10 05:00'
并最终离开'2015-06-10 06:00'
工作。
我无法进行只向我显示此类内容的查询:
'2015-06-10 09:00'
这是我需要的输出。即使用户可以有多个细节,我也需要显示他的第一个入口日期时间和最后一个日期时间,并附上一个专栏,说明他在工作时间为22:00和次日凌晨6点的工作时数和分钟数
蒂姆,你的查询很完美,但它几近接近。但是,当用户在22点之后(我的样本显示)时,我不知道如何获得小时:分钟:秒。答案 0 :(得分:0)
计算总工作时间应该更容易,假设工人可以在晚上8点之后上班,最多工作10个小时(你可以调整):
select userid, time_ins, cnt_start, time_outs, cnt_end, seconds, TIME_FORMAT(SEC_TO_TIME(seconds),'%H:%i:%s') as night_shift
from (
select userid, time_ins, cnt_start, time_outs, cnt_end,
(select sum(timestampdiff(second, cnt_start,
case when fecha_ingreso < a.cnt_start then a.cnt_start
when fecha_ingreso > a.cnt_end then a.cnt_end
else fecha_ingreso end ) * case when tipo =1 then -1 else 1 end ) seconds
from test_t n
where n.userid = a.userid and n.fecha_ingreso >= a.time_ins and n.fecha_ingreso <=a.time_outs) seconds
from (
select userid, time_ins, cnt_start, time_outs ,
case when cast(time_outs as date) = cast(time_ins as date) then time_outs
when cast(time_outs as time)>'06:00:00' then date_add(date(time_outs), interval 6 hour) end cnt_end
from (
select userid, time_enter as time_ins , case when cast(time_enter as time) < '20:00:00' then
date_add(date(time_enter), interval 22 hour)
else time_enter end as cnt_start,
(select max(fecha_ingreso) from test_t l where l.userid=e.userid and l.tipo=2 and l.fecha_ingreso > e.time_enter
and l.fecha_ingreso < date_add(e.time_enter, interval 22 hour) )
as time_outs
from (
select userid, min(fecha_ingreso) as time_enter
from test_t
where cast(fecha_ingreso as time)>='06:00:00'
and tipo=1
group by userid ,cast(fecha_ingreso as date)
) e
) t
) a
) ff;
我没有对其进行优化,因此您可以看到这些步骤。
您可以尝试:
select l1.* from l1
left join (
select l.id, m.id mid from l1 l
join l1 m
on l.userid=m.userid and l.tipo=2 and m.tipo=1 and l.fecha_ingreso >=date_add(m.fecha_ingreso, interval -1 hour)
and l.id < m.id) x
on l1.id=x.id or l1.id =x.mid
where mid is null;
它返回
# id, userid, fecha_ingreso, tipo
'1', '1', '2015-06-08 20:00:00', '1'
'3', '1', '2015-06-09 05:00:00', '2'
'18', '2', '2015-06-09 23:30:00', '1'
'21', '2', '2015-06-10 09:00:00', '2'
'22', '1', '2015-06-09 23:30:00', '1'
'25', '1', '2015-06-10 09:00:00', '2'
在1小时内过滤掉同一用户的1-2个条目。