mysql - 计算工作时间的两行之间的时间差
问题描述
我有一张桌子:
timedate workclock
2018-01-01 09:00:00 check-in
2018-01-01 12:30:40 check-in
2018-01-02 09:00:00 check-in
2018-01-02 11:29:00 check-out
2018-01-03 14:29:00 check-out
我需要输出看起来像这样:
date checkin checkout working-time
2018-01-01 09:00 none missing checkout
2018-01-02 09:00 11:29 02:29
2018-01-03 none 14:29 missing checkin
我无法加入行,因此将不胜感激有第三个 col 代表工人标签,但这应该很容易分组。
解决方案
可能有更好的方法来执行此操作,但这里是您可以通过三部分查询来执行此操作的方法。
首先,找到所有签到并使用子查询选择当天签到之后的第一个签出。
select
date(t1.timedate) as date,
time(t1.timedate) as checkin,
(
select time(t2.timedate)
from timetracker t2
where workclock = 'check-out'
and date(t2.timedate) = date(t1.timedate)
and t1.timedate < t2.timedate
) as checkout
from timetracker t1
where t1.workclock = 'check-in'
+------------+----------+----------+
| date | checkin | checkout |
+------------+----------+----------+
| 2018-01-01 | 09:00:00 | NULL |
| 2018-01-01 | 12:30:40 | NULL |
| 2018-01-02 | 09:00:00 | 11:29:00 |
+------------+----------+----------+
注意:我假设您缺少集合中的 12:30:40 行。
然后在一个单独的查询中,找到所有没有签入的签出。这是通过针对签入行的自联接来完成的。
select
date(t3.timedate) as date,
null as checkin,
time(t3.timedate) as checkout
from timetracker t3
left join timetracker t4
on date(t3.timedate) = date(t4.timedate) and
t4.workclock = 'check-in'
where t3.workclock = 'check-out'
and t4.timedate is null
+------------+---------+----------+
| date | checkin | checkout |
+------------+---------+----------+
| 2018-01-03 | NULL | 14:29:00 |
+------------+---------+----------+
union
他们在一起。
select
date(t1.timedate) as date,
time(t1.timedate) as checkin,
(
select time(t2.timedate)
from timetracker t2
where workclock = 'check-out'
and date(t2.timedate) = date(t1.timedate)
and t1.timedate < t2.timedate
order by t2.timedate
limit 1
) as checkout
from timetracker t1
where t1.workclock = 'check-in'
union
select
date(t3.timedate) as date,
null as checkin,
time(t3.timedate) as checkout
from timetracker t3
left join timetracker t4
on date(t3.timedate) = date(t4.timedate) and
t4.workclock = 'check-in'
where t3.workclock = 'check-out'
and t4.timedate is null
+------------+----------+----------+
| date | checkin | checkout |
+------------+----------+----------+
| 2018-01-01 | 09:00:00 | NULL |
| 2018-01-01 | 12:30:40 | NULL |
| 2018-01-02 | 09:00:00 | 11:29:00 |
| 2018-01-03 | NULL | 14:29:00 |
+------------+----------+----------+
最后一部分是格式化和排序。与其尝试在这个已经很庞大的查询中执行此操作,不如为格式化创建一个新查询。将此查询用作子查询表。
select
t.date,
case
when t.checkin is null then
'none'
else
t.checkin
end as "checkin",
case
when t.checkout is null then
'none'
else
t.checkout
end as "checkout",
case
when checkout is null then
'missing checkout'
when checkin is null then
'missing checkin'
else
time(checkout - checkin)
end as "working-time"
from (
select ...
union
select ...
) t
order by t.date, t.checkin
+------------+----------+----------+------------------+
| date | checkin | checkout | working-time |
+------------+----------+----------+------------------+
| 2018-01-01 | 09:00:00 | none | missing checkout |
| 2018-01-01 | 12:30:40 | none | missing checkout |
| 2018-01-02 | 09:00:00 | 11:29:00 | 02:29:00 |
| 2018-01-03 | none | 14:29:00 | missing checkin |
+------------+----------+----------+------------------+
或者省点麻烦,在接收端进行格式化。
推荐阅读
- javascript - Reactjs 如何只更新 html dom 元素中的部分文本?
- intersection - 对移动物体进行光线投射
- r - 体素包中带有 plotGAM() 函数的 GAM 图
- python - python range 类实例属性如何只读?
- rabbitmq - RabbitMQ:确认消息到达队列
- python - Seaborn 热图 - 删除多余的重复 Xticks
- html - 角度引导 div 宽度仅在 ipad 上未显示完整
- javascript - 无法在“MediaDevices”上执行“getUserMedia”:不支持 getUserMedia
- reactjs - React dangerouslySetInnerHTML 正在为图像道具渲染 [object object]
- python - 如何给 pylint 提供论据