mysql - Mysql Foreach 从一张表到另一张表
问题描述
我有 2 个表,第一个表是用户,第二个表是 user_attendance。
在用户考勤中,我每行插入 IN 和 OUT,因此 1 行用于 IN,1 行用于 OUT。
我想要一个 MySQL 选择(所以我不必在 Php 上做),它将循环用户中的每个 ID,并在用户表中获取该用户的最后一个 OUT 和第一个 IN。
我尝试在 Php 上执行此操作,首先选择用户中的所有 ID,然后通过 php 循环并选择该 ID 中的第一个和最后一个。像这样。
$userCreds = DB::table('users')->select('user_id', 'username')->get();
$emailBody = '<table border="1"><thead><tr><th>Employee ID</th><th>Employee Name</th><th>Date</th><th>IN</th><th>OUT</th></tr></thead><tbody>';
foreach ($userCreds as $userCred) {
$userAttendance = DB::select(
DB::raw(
"SELECT username,
(
SELECT TIME_FORMAT(time(b.server_time), '%r')
FROM `users` a
LEFT JOIN user_attendance b
ON a.user_id = b.user_id
WHERE a.user_id = $userCred->user_id
AND (b.server_time between '$ysDate' and '$yeDate')
AND b.action = 'IN' ORDER BY b.server_time ASC LIMIT 1
) as TimeIn,
(
SELECT TIME_FORMAT(time(b.server_time), '%r')
FROM `users` a
LEFT JOIN user_attendance b
ON a.user_id = b.user_id
WHERE a.user_id = $userCred->user_id
AND (b.server_time between '$ysDate' and '$yeDate')
AND b.action = 'OUT' ORDER BY b.server_time DESC LIMIT 1
) as TimeOut
FROM users
WHERE user_id = $userCred->user_id"
)
);
$emailBody .= '<tr><td>'.$userCred->user_id.'</td><td>'.$userCred->username.'</td><td>'.date('Y-m-d',(strtotime ( '-1 day' , strtotime ( $date) ) )).'</td><td>'.$userAttendance[0]->TimeIn.'</td><td>'.$userAttendance[0]->TimeOut.'</td></tr>';
}
我希望在 Mysql 端完成,而不是在 Php 上完成,这样我就可以创建一个视图,该视图现在将永远存储并用于记录目的。
我需要的是这样的
用户表
用户 ID | 用户名
01 | 小猪
02 | 呸
03 | 老虎
user_attendance 表
用户 ID | 服务器时间 | 行动
01 | 2019-10-10 08:00:00 | 在
01 | 2019-10-10 09:00:00 | 出去
01 | 2019-10-10 10:00:00 | 在
01 | 2019-10-10 18:00:00 | 出去
02 | 2019-10-10 07:45:00 | 在
02 | 2019-10-10 09:00:00 | 出去
02 | 2019-10-10 10:00:00 | 在
02 | 2019-10-10 19:50:00 | 出去
结果将是
用户 ID | 日期 | 输入 | 出去
01 | 2019-20-10 | 08:00:00 | 18:00:00
02 | 2019-20-10 | 07:45:00 | 19:50:00
解决方案
这是重构的sql
查询。
首先是获取您的用户表,第二是加入IN
时间,第三是加入OUT
时间,第四是获取用户 ID 的时间max()
和min()
时间,然后按 a.user_id 分组。
SELECT a.user_id, TIME_FORMAT(time(min(b.server_time)), '%r') as TimeIn, TIME_FORMAT(time(max(c.server_time)), '%r') as TimeOut
FROM `users` a
LEFT JOIN user_attendance b ON a.user_id = b.user_id and (b.server_time between '$ysDate' and '$yeDate') and b.action = 'IN'
LEFT JOIN user_attendance c ON a.user_id = c.user_id and (c.server_time between '$ysDate' and '$yeDate') and c.action = 'OUT'
GROUP BY a.user_id
推荐阅读
- python - 如何处理 Python 中的斜线和 %2F?
- web-services - SOAP 服务的“代表”
- docker - 在 Chaincode Dev 模式下为 Fabric 添加新链码的位置
- css - 在我的叠加层上叠加文本
- android - 从我们自己的服务器而不是 Play 商店分发的 Android 应用程序的推荐/邀请跟踪
- ruby-on-rails - 设计 - 没有 active_for_authentication 的 bypass_sign_in?打回来
- c# - Windows XP 上捆绑的 .NET 应用程序
- arduino - 随时间绘制 PWM 的简单方法
- java - 在 Glassfish 上执行应用程序时出错
- xquery - 如何在marklogic中对字符串日期进行排序?