[英]Mysql select the latest record between current day or next day
I have a dataset of daily In and Out times of employees as follows: 我有一个员工的每日进出时间的数据集,如下所示:
uuid datetime Status
7 2019-08-07 07:15:56 Checkout
7 2019-08-06 19:06:00 Checkin
7 2019-08-06 19:05:49 Checkout
7 2019-08-06 08:49:57 Checkin
7 2019-08-06 08:49:46 Checkout
7 2019-08-05 19:00:52 Checkin
7 2019-08-04 17:10:13 Checkout
7 2019-08-04 08:50:04 Checkin
7 2019-08-04 08:49:47 Checkout
7 2019-08-03 18:10:23 Checkin
7 2019-08-03 18:10:13 Checkout
7 2019-08-03 08:41:44 Checkin
7 2019-08-03 08:41:31 Checkout
7 2019-08-02 19:04:55 Checkin
7 2019-08-02 19:04:43 Checkout
7 2019-08-02 08:54:06 Checkin
7 2019-08-02 08:53:49 Checkout
7 2019-08-01 18:55:05 Checkin
7 2019-08-01 07:16:47 Checkout
7 2019-07-31 18:28:11 Checkin
7 2019-07-31 07:15:24 Checkout
7 2019-07-30 19:05:45 Checkin
7 2019-07-30 19:05:33 Checkout
7 2019-07-30 08:56:11 Checkin
7 2019-07-30 08:56:00 Checkout
Using this data I wanted to calculate the total number of hours worked during the day. 使用此数据,我想计算一天中的总工作时间。 The default shifts as 07.00 till 16:00 and 16:00 till 01:00 next day.
默认值从第二天的07.00转移到16:00,从16:00转移到01:00。 From 01:00 till 06:00 OT time.
OT时间从01:00到06:00。
My challenge was when an employee Checkins at 07:00 and works till next day morning till 03:00 (both the shifts + few OT hours) I used the following SQL to retrieve the Checkout time but it only return results if checking happens on the same day. 我的挑战是,当一名员工在07:00签入并工作到第二天早上直到03:00(轮班+几个OT时间)时,我使用以下SQL来检索Checkout时间,但它仅在检查发生在同一天。 I'm unable to retrieve results if Checkout time was 03:00, 3:30, 4:00, etc...
如果结帐时间为03:00、3:30、4:00等,我将无法检索结果。
Also there cam be more that one chekins & checkouts that can take place but have to consider the earliest checkin and the latest checkout 此外,可能还会发生一种以上的结账和退房,但必须考虑最早的退房和最新的退房
In the following QUERY I'm trying to retrieve the Checkout time, it only return results if checkout time exists for the same day not if it happens after midnight. 在下面的QUERY中,我尝试检索Checkout时间,它仅在同一天存在checkout时才返回结果,而不是在午夜之后发生。
SELECT uuid, DATE_FORMAT(datetime, "%M %d %Y") AS outdate, DATE_FORMAT(datetime, "%H:%i") AS outtimes FROM attendance_logs WHERE status = 'Checkout' AND (DATE_FORMAT(datetime, "%Y-%m-%d %H:%i:%s") BETWEEN DATE_FORMAT(datetime, "%Y-%m-%d 13:00:00") AND DATE_FORMAT(DATE_ADD(datetime, INTERVAL 1 DAY), "%Y-%m-%d 09:30:00")) AND DATE_FORMAT(datetime, "%Y-%m-%d") < "2019-08-08" ORDER BY datetime DESC
Expected Output (Edited to fix the result on 2019-08-05) 预期输出(已编辑以将结果固定在2019-08-05)
uuid date Checkin Checkout
7 2019-08-06 08:49:57 07:15:56
7 2019-08-05 19:00:52 08:49:46
7 2019-08-04 08:50:04 17:10:13
7 2019-08-03 08:41:44 08:49:47
7 2019-08-02 08:54:06 08:41:31
7 2019-08-01 18:55:05 08:53:49
7 2019-07-31 07:16:47 18:28:11
7 2019-07-30 08:56:11 07:15:24
Final SQL query 最终SQL查询
select attendance_logs.uuid
, emp.name
, dept.name AS department_name
, DATE_FORMAT(attendance_logs.datetime
, "%M %d %Y") AS day
, cintimes.intimes AS cin
, couttimes.outtimes AS cout
from attendance_logs
left
join employees AS emp
on emp.uuid = attendance_logs.uuid
and emp.is_disabled = 0
and emp.is_valid = 1
left
join departments AS dept
on dept.id = attendance_logs.department_id
and dept.is_disabled = 0
and dept.is_valid = 1
left
join
( SELECT uuid
, DATE_FORMAT(datetime, "%M %d %Y") AS indate
, DATE_FORMAT(datetime, "%H:%i") AS intimes
FROM attendance_logs
WHERE status = 'Checkin'
AND DATE_FORMAT(datetime, "%Y-%m-%d") <= "2019-08-07"
GROUP
BY DATE_FORMAT(datetime, "%M %d %Y")
, uuid
ORDER
BY datetime DESC ) AS cintimes
on cintimes.uuid = attendance_logs.uuid
and cintimes.indate = DATE_FORMAT(attendance_logs.datetime, "%M %d %Y")
left
join
( SELECT uuid
, DATE_FORMAT(datetime, "%M %d %Y") AS outdate
, DATE_FORMAT(datetime, "%H:%i") AS outtimes
FROM attendance_logs
WHERE status = 'Checkout'
AND (DATE_FORMAT(datetime, "%Y-%m-%d %H:%i:%s") BETWEEN DATE_FORMAT(datetime, "%Y-%m-%d 13:00:00") AND DATE_FORMAT(DATE_ADD(datetime, INTERVAL 1 DAY), "%Y-%m-%d 09:30:00"))
AND DATE_FORMAT(datetime, "%Y-%m-%d") < "2019-08-07"
ORDER
BY datetime DESC ) AS couttimes
on couttimes.uuid = attendance_logs.uuid
and couttimes.outdate = DATE_FORMAT(attendance_logs.datetime, "%M %d %Y")
where attendance_logs.uuid = ?
group
by DATE_FORMAT(attendance_logs.datetime, "%M %d %Y")
, attendance_logs.uuid
order
by attendance_logs.datetime desc
You might want to format it a little bit, but I think that's what you want: 您可能需要格式化一下,但是我想这就是您想要的:
select
al.uuid,
al.datetime as checkin,
(
select min(datetime)
from attendance_logs
where status = 'CheckOut' and datetime > al.datetime
) as checkout
from attendance_logs al
where al.status = 'CheckIn';
Data set: 数据集:
SELECT * FROM my_table;
+------+---------------------+----------+
| uuid | datetime | Status |
+------+---------------------+----------+
| 7 | 2019-07-30 08:56:00 | Checkout |
| 7 | 2019-07-30 08:56:11 | Checkin |
| 7 | 2019-07-30 19:05:33 | Checkout |
| 7 | 2019-07-30 19:05:45 | Checkin |
| 7 | 2019-07-31 07:15:24 | Checkout |
| 7 | 2019-07-31 18:28:11 | Checkin |
| 7 | 2019-08-01 07:16:47 | Checkout |
| 7 | 2019-08-01 18:55:05 | Checkin |
| 7 | 2019-08-02 08:53:49 | Checkout |
| 7 | 2019-08-02 08:54:06 | Checkin |
| 7 | 2019-08-02 19:04:43 | Checkout |
| 7 | 2019-08-02 19:04:55 | Checkin |
| 7 | 2019-08-03 08:41:31 | Checkout |
| 7 | 2019-08-03 08:41:44 | Checkin |
| 7 | 2019-08-03 18:10:13 | Checkout |
| 7 | 2019-08-03 18:10:23 | Checkin |
| 7 | 2019-08-04 08:49:47 | Checkout |
| 7 | 2019-08-04 08:50:04 | Checkin |
| 7 | 2019-08-04 17:10:13 | Checkout |
| 7 | 2019-08-05 19:00:52 | Checkin |
| 7 | 2019-08-06 08:49:46 | Checkout |
| 7 | 2019-08-06 08:49:57 | Checkin |
| 7 | 2019-08-06 19:05:49 | Checkout |
| 7 | 2019-08-06 19:06:00 | Checkin |
| 7 | 2019-08-07 07:15:56 | Checkout |
+------+---------------------+----------+
Here's a partial result... 这是部分结果...
SELECT x.uuid
, x.datetime checkin
, MIN(y.datetime) checkout
FROM my_table x
LEFT
JOIN my_table y
ON y.datetime > x.datetime
AND y.status = 'checkout'
WHERE x.status = 'checkin'
GROUP
BY x.datetime;
+------+---------------------+---------------------+
| uuid | checkin | checkout |
+------+---------------------+---------------------+
| 7 | 2019-07-30 08:56:11 | 2019-07-30 19:05:33 |
| 7 | 2019-07-30 19:05:45 | 2019-07-31 07:15:24 |
| 7 | 2019-07-31 18:28:11 | 2019-08-01 07:16:47 |
| 7 | 2019-08-01 18:55:05 | 2019-08-02 08:53:49 |
| 7 | 2019-08-02 08:54:06 | 2019-08-02 19:04:43 |
| 7 | 2019-08-02 19:04:55 | 2019-08-03 08:41:31 |
| 7 | 2019-08-03 08:41:44 | 2019-08-03 18:10:13 |
| 7 | 2019-08-03 18:10:23 | 2019-08-04 08:49:47 |
| 7 | 2019-08-04 08:50:04 | 2019-08-04 17:10:13 |
| 7 | 2019-08-05 19:00:52 | 2019-08-06 08:49:46 |
| 7 | 2019-08-06 08:49:57 | 2019-08-06 19:05:49 |
| 7 | 2019-08-06 19:06:00 | 2019-08-07 07:15:56 |
+------+---------------------+---------------------+
I still can't follow the logic that gets us from here to your desired result. 我仍然无法遵循使我们从这里到达您想要的结果的逻辑。
EDIT: 编辑:
Here's something that looks very like your desired result, but I don't know if it's really what you're after... 这看起来很像您想要的结果,但是我不知道这是否真的是您想要的...
SELECT uuid
, MIN(checkin) checkin
, MAX(checkout) checkout
FROM
( SELECT x.uuid
, x.datetime checkin
, MIN(y.datetime) checkout
, DATE(x.datetime-INTERVAL 8 HOUR) dt
FROM my_table x
LEFT
JOIN my_table y
ON y.uuid = x.uuid
AND y.datetime > x.datetime
AND y.status = 'checkout'
WHERE x.status = 'checkin'
GROUP
BY x.datetime
) a
GROUP
BY uuid
, dt;
+------+---------------------+---------------------+
| uuid | checkin | checkout |
+------+---------------------+---------------------+
| 7 | 2019-07-30 08:56:11 | 2019-07-31 07:15:24 |
| 7 | 2019-07-31 18:28:11 | 2019-08-01 07:16:47 |
| 7 | 2019-08-01 18:55:05 | 2019-08-02 08:53:49 |
| 7 | 2019-08-02 08:54:06 | 2019-08-03 08:41:31 |
| 7 | 2019-08-03 08:41:44 | 2019-08-04 08:49:47 |
| 7 | 2019-08-04 08:50:04 | 2019-08-04 17:10:13 |
| 7 | 2019-08-05 19:00:52 | 2019-08-06 08:49:46 |
| 7 | 2019-08-06 08:49:57 | 2019-08-07 07:15:56 |
+------+---------------------+---------------------+
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.