问题描述
我正在使用 zkteco-sdk-php 从 ZK 考勤设备检索数据。
结果是这样的
UID | ID | 姓名 | 状态 | 日期 | 时间 | 类型 |
---|---|---|---|---|---|---|
55 | 275 | 雇佣 1 | 指纹 | 19-06-2021 | 08:14:16 | 签到 |
55 | 275 | 雇佣 1 | 指纹 | 19-06-2021 | 11:15:20 | 退房 |
*而且所有的数据都不是按用户排序的,而是按第一个指纹考勤排序的,所以日志会随着不同用户和不同类型的考勤而混淆
我想将检索到的数据插入数据库,问题是正在检索数据 每个日志(签入或签出)作为单行 我想在同一天插入(签入&签出同一行中的同一用户)
这就是我的目标
ID | 用户 ID | 签到 | 退房 |
---|---|---|---|
55 | 275 | 19-06-2021 08:14:16 | 19-06-2021 11:15:20 |
这是从zk中检索数据的代码
$attendance = $zk->getAttendance();
if (count($attendance) > 0) {
$attendance = array_reverse($attendance,true);
sleep(1);
foreach ($attendance as $attItem) {
?>
<tr>
<td><?PHP echo($attItem['uid']); ?></td>
<td><?PHP echo($attItem['id']); ?></td>
<td><?PHP echo(isset($users[$attItem['id']]) ? $users[$attItem['id']]['name'] : $attItem['id']); ?></td>
<td><?PHP echo(ZK\Util::getAttState($attItem['state'])); ?></td>
<td><?PHP echo(date("d-m-Y",strtotime($attItem['timestamp']))); ?></td>
<td><?PHP echo(date("H:i:s",strtotime($attItem['timestamp']))); ?></td>
<td><?PHP echo(ZK\Util::getAttType($attItem['type'])); ?></td>
</tr>
解决方法
MySQL:
SELECT
t1.ID,t1.UserID,ADDTIME(CONVERT(t1.`date`,DATETIME),t1.`time`) as "Check-in",ADDTIME(CONVERT(t2.`date`,t2.`time`) as "Check-out"
FROM table t1
LEFT JOIN table t2 ON t2.ID=t1.ID
and t2.UserID=t1.UserID
and t2.Type = 'Check-out'
WHERE
ID = 55
and UserID = 275
and Type = 'Check-in'
注意:您需要用正确的表名替换 table
。
在很多地方都可以找到有关如何在 PHP 中使用此 SQL 查询的不同示例,例如:Google: how to query MySQL from PHP
,您应该“按原样”存储日志 - 将行分开以进行签入和签出,并在选择时通过 UUID
和 ID
连接两行:
select
log_in.uuid,log_in.id,log_in.name,log_in.state,log_in.event_time as log_in_time,log_out.event_time as log_out_time
from zk_log log_in
join zk_log log_out on log_in.uuid = log_out.uuid and log_in.id = log_out.id
where log_in.event_type = 'check-in' and log_out.event_type = 'check-out';
,
我认为可以这样实现:
SELECT UID,ID,CONCAT(date,' ',MIN(time)) AS Check_in,MAX(time)) AS Check_out
FROM attendance
GROUP BY date,UID,ID;
但我必须指出,您示例中的 date
数据不是标准的 MySQL DATE
数据类型,并且您要插入的目标表是否具有如下结构:
destination_table
(UID INT,ID INT,Check_in DATETIME,<--- this datatype
Check_out DATETIME); <---
插入不会成功,会返回错误:
日期时间值不正确:第 1 行的“Check_in”列的“19-06-2021 08:14:16”
否则,如果 destination_table
数据类型为 VARCHAR()
,则插入不会有问题。但是,我强烈建议在目标表上至少使用标准格式。因此,如果源表确实将日期存储为 VARCHAR()
并且目标表使用的是 DATETIME
数据类型,则您将需要 STR_TO_DATE()
:
INSERT INTO destination_table
SELECT UID,CONCAT(STR_TO_DATE(date,'%d-%m-%Y'),ID;