MySQL:内部连接时重复行

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL:内部连接时重复行相关的知识,希望对你有一定的参考价值。

我是这个网站的新手。我正在尝试为我在phpmysql中创建的考勤系统找到关于这个重复行问题的解决方案。

在该系统中,每个用户可以执行每个工作日的签到和签出。一些用户可以在一天内执行多次签到和退房以进行轮班工作,忽略LATE状态(在登记入住时的9.05am之后)和EARLY状态(在退房时的下午5:00之前)。 MySQL系统中有三个表用于此系统。

用于存储签入数据的tbl_checkin在数据库中包含以下内容:

ID     User_Id     Date          Time     Late_status          Comment
------------------------------------------------------------------------------------------
1     UGT001     2017-12-29     08:14:13                   No Comment
2     UGT002     2017-12-29     09:54:52     LATE          Comment Goes Here
3     UGT001     2017-12-30     09:16:34     LATE          Sending kids to school
4     UGT002     2017-12-30     08:21:04               
5     UGT003     2018-01-02     08:05:11                   
6     UGT003     2018-01-02     12:05:32                   Second Checkin

tbl_checkout,用于存储签出数据:

ID     User_Id     Date          Time     Early_status          Comment
------------------------------------------------------------------------------------------
1     UGT001     2017-12-29     17:14:13                   
2     UGT002     2017-12-29     15:54:13     EARLY         Hospital Appointment
3     UGT001     2017-12-30     16:58:21     EARLY         Late for movie night
4     UGT002     2017-12-30     18:00:43               
5     UGT003     2018-01-02     10:30:44                   Break Time
6     UGT003     2018-01-02     18:04:45                   

tbl_userlogin,用于存储用户数据(以及此处未显示的其他信息,如工作开始日期,结束日期,密码,持续时间,角色和用户状态):

ID     User_Id     Name          
------------------------------------------------------------------------------------------
1     UGT001     KEVIN MARTIN                 
2     UGT002     AHMAD BIN IBRAHIM  
3     UGT003     ALISYA PUTRI KARISMA

对于这个问题,我使用此SQL查询显示一个完整的考勤日志,显示用户名,用户ID,日期,检查时间,签出时间,签入注释和签出评论,排序最新条目(按日期)第一:

SELECT DISTINCT 
    b.name AS Name, 
    c.user_id AS User_ID , 
    c.date AS Date, 
    a.time As "Time In",
    c.time As "Time Out",
    a.comment AS "Comment In",
    c.comment AS "Comment Out" 
FROM 
tbl_checkout c 
LEFT JOIN tbl_checkin a ON c.date=a.date AND c.user_id=a.user_id 
INNER JOIN tbl_userlogin b ON c.user_id=b.user_id 
ORDER BY c.date DESC

这是我应该显示的结果:

Name                    User_ID     Date         Time In     Time Out     Comment In               Comment Out
----------------------------------------------------------------------------------------------------------------------
ALISYA PUTRI KARISMA    UGT003    2018-01-02    12:05:32     18:04:45    Second Checkin           
ALISYA PUTRI KARISMA    UGT003    2018-01-02    08:05:11     10:30:44                            Break Time
KEVIN MARTIN            UGT001    2017-12-30    09:16:34     16:58:21    Sending kids to school   Late for movie night
AHMAD BIN IBRAHIM       UGT002    2017-12-30    08:21:04     18:00:43
AHMAD BIN IBRAHIM       UGT002    2017-12-29    09:54:52     15:54:13    Comment Goes Here        Hospital Appointment
KEVIN MARTIN            UGT001    2017-12-29    08:14:13     17:14:13    No Comment

但是,执行此SQL查询将显示如下:

Name                    User_ID     Date         Time In     Time Out     Comment In               Comment Out
----------------------------------------------------------------------------------------------------------------------
ALISYA PUTRI KARISMA    UGT003    2018-01-02    12:05:32     10:30:44    Second Checkin           Break Time
ALISYA PUTRI KARISMA    UGT003    2018-01-02    08:05:11     18:04:45    
ALISYA PUTRI KARISMA    UGT003    2018-01-02    12:05:32     18:04:45    Second Checkin           
ALISYA PUTRI KARISMA    UGT003    2018-01-02    08:05:11     10:30:44                            Break Time
KEVIN MARTIN            UGT001    2017-12-30    09:16:34     16:58:21    Sending kids to school   Late for movie night
AHMAD BIN IBRAHIM       UGT002    2017-12-30    08:21:04     18:00:43
AHMAD BIN IBRAHIM       UGT002    2017-12-29    09:54:52     15:54:13    Comment Goes Here        Hospital Appointment
KEVIN MARTIN            UGT001    2017-12-29    08:14:13     17:14:13    No Comment

从上面的结果看UGT003(这个用户可以执行多个签入和退出/班次安排),重复阅读,因为阅读不同的入住时间/评论和签出时间/评论。

有人可以帮助我的出勤系统解决这个问题吗?谢谢。

答案

问题是你只使用date加入签到和结账,如果在一天内有多个,那就不足以匹配它们。它将每一个in与每天的out相匹配,这会导致重复(当更多的情况被添加到同一日期时甚至是乘法)。

试试这个查询:

SELECT
    b.name AS Name, 
    c.user_id AS User_ID , 
    c.date AS Date, 
    a.time As "Time In",
    c.time As "Time Out",
    a.comment AS "Comment In",
    c.comment AS "Comment Out"
FROM 
tbl_checkin a
LEFT JOIN tbl_checkout c ON c.date=a.date AND c.user_id=a.user_id AND c.Time >= a.Time
LEFT JOIN tbl_checkout co2 ON co2.user_id=c.user_id AND c.date=co2.date  AND co2.Time >= a.Time AND co2.Time < c.Time
INNER JOIN tbl_userlogin b ON c.user_id=b.user_id 


WHERE 
    co2.ID IS NULL

ORDER BY c.date DESC, a.Time, c.Time

以上是关于MySQL:内部连接时重复行的主要内容,如果未能解决你的问题,请参考以下文章

如何创建片段以重复变量编号中的代码行

mysql内部连接条件忽略重复的ID

PHP MySQL内部连接具有相同的列名[重复]

从片段内部调用活动方法[重复]

MySQL连接和连接行而不重复条目[重复]

片段内部未调用 onActivityResult [重复]