从考勤表MYSQL中查找最后一名和最后一名
我有一个MYSQL考勤表,记录如下:从考勤表MYSQL中查找最后一名和最后一名,mysql,Mysql,我有一个MYSQL考勤表,记录如下: Id DateTime Door Employee_id 1 2016-01-01 08:00:00 In 100 2 2016-01-01 09:00:00 Out 100 3 2016-01-01 09:15:00 In 100 4 2016-01-01 09:30:00 In 100 5 2016-01-01 10:00:00 Out
Id DateTime Door Employee_id
1 2016-01-01 08:00:00 In 100
2 2016-01-01 09:00:00 Out 100
3 2016-01-01 09:15:00 In 100
4 2016-01-01 09:30:00 In 100
5 2016-01-01 10:00:00 Out 100
6 2016-01-01 11:00:00 In 100
7 2016-01-01 12:00:00 In 100
8 2016-01-01 13:00:00 In 100
9 2016-01-01 13:30:00 Out 100
10 2016-01-01 14:00:00 Out 100
11 2016-01-01 15:00:00 In 100
我希望输出为最后一个时钟输入和最后一个时钟输出,如下所示。如果在最后一次时钟输入后没有时钟输出,只需忽略时钟输入
Id Clock In Clock Out Employee Id
1 2016-01-01 08:00:00 2016-01-01 09:00:00 100
2 2016-01-01 09:30:00 2016-01-01 10:00:00 100
3 2016-01-01 13:00:00 2016-01-01 14:00:00 100
我真的不知道该怎么做。我问过我的同事,目瞪口呆地寻找答案,但运气不好。非常感谢你们的帮助。提前感谢。这是间隙问题的一种变体。首先枚举
in
s和out
s中的,使连续值组具有相同的值。然后您就可以使用聚合了
因此:
这是一个SQL问题。这是间隙问题的变体。首先枚举in
s和out
s中的,使连续值组具有相同的值。然后您就可以使用聚合了
因此:
这是一个带有演示的解决方案
SQL:
输出:
mysql> SELECT * FROM attendance;
+------+---------------------+------+
| Id | DateTime | Door |
+------+---------------------+------+
| 1 | 2016-01-01 08:00:00 | In |
| 2 | 2016-01-01 09:00:00 | Out |
| 3 | 2016-01-01 09:15:00 | In |
| 4 | 2016-01-01 09:30:00 | In |
| 5 | 2016-01-01 10:00:00 | Out |
| 6 | 2016-01-01 11:00:00 | In |
| 7 | 2016-01-01 12:00:00 | In |
| 8 | 2016-01-01 13:00:00 | In |
| 9 | 2016-01-01 13:30:00 | Out |
| 10 | 2016-01-01 14:00:00 | Out |
| 11 | 2016-01-01 15:00:00 | In |
+------+---------------------+------+
11 rows in set (0.00 sec)
mysql>
mysql> -- SQL needed:
mysql> SELECT
-> @id:=@id+1 Id,
-> MAX(IF(Door = 'In', DateTime, NULL)) `Check In`,
-> MAX(IF(Door = 'Out', DateTime, NULL)) `Check Out`
-> FROM
-> (SELECT
-> *,
-> CASE
-> WHEN
-> (door = 'In' AND @last_door = '') OR
-> (door = 'In' AND @last_door = 'In') OR
-> (door = 'Out' AND @last_door = 'In') OR
-> (door = 'Out' AND @last_door = 'Out')
-> THEN @group_num
-> WHEN
-> (door = 'In' AND @last_door = 'Out')
-> THEN @group_num:=@group_num+1
-> ELSE 0
-> END door_group,
-> @last_door:=Door
-> FROM attendance
-> JOIN (SELECT @group_num:=1) a
-> ) t JOIN (SELECT @id:=0) b
-> GROUP BY t.door_group
-> HAVING SUM(Door = 'In') > 0 AND SUM(Door = 'Out') > 0;
+------+---------------------+---------------------+
| Id | Check In | Check Out |
+------+---------------------+---------------------+
| 1 | 2016-01-01 08:00:00 | 2016-01-01 09:00:00 |
| 2 | 2016-01-01 09:30:00 | 2016-01-01 10:00:00 |
| 3 | 2016-01-01 13:00:00 | 2016-01-01 14:00:00 |
+------+---------------------+---------------------+
3 rows in set (0.00 sec)
这是一个带有演示的解决方案
SQL:
输出:
mysql> SELECT * FROM attendance;
+------+---------------------+------+
| Id | DateTime | Door |
+------+---------------------+------+
| 1 | 2016-01-01 08:00:00 | In |
| 2 | 2016-01-01 09:00:00 | Out |
| 3 | 2016-01-01 09:15:00 | In |
| 4 | 2016-01-01 09:30:00 | In |
| 5 | 2016-01-01 10:00:00 | Out |
| 6 | 2016-01-01 11:00:00 | In |
| 7 | 2016-01-01 12:00:00 | In |
| 8 | 2016-01-01 13:00:00 | In |
| 9 | 2016-01-01 13:30:00 | Out |
| 10 | 2016-01-01 14:00:00 | Out |
| 11 | 2016-01-01 15:00:00 | In |
+------+---------------------+------+
11 rows in set (0.00 sec)
mysql>
mysql> -- SQL needed:
mysql> SELECT
-> @id:=@id+1 Id,
-> MAX(IF(Door = 'In', DateTime, NULL)) `Check In`,
-> MAX(IF(Door = 'Out', DateTime, NULL)) `Check Out`
-> FROM
-> (SELECT
-> *,
-> CASE
-> WHEN
-> (door = 'In' AND @last_door = '') OR
-> (door = 'In' AND @last_door = 'In') OR
-> (door = 'Out' AND @last_door = 'In') OR
-> (door = 'Out' AND @last_door = 'Out')
-> THEN @group_num
-> WHEN
-> (door = 'In' AND @last_door = 'Out')
-> THEN @group_num:=@group_num+1
-> ELSE 0
-> END door_group,
-> @last_door:=Door
-> FROM attendance
-> JOIN (SELECT @group_num:=1) a
-> ) t JOIN (SELECT @id:=0) b
-> GROUP BY t.door_group
-> HAVING SUM(Door = 'In') > 0 AND SUM(Door = 'Out') > 0;
+------+---------------------+---------------------+
| Id | Check In | Check Out |
+------+---------------------+---------------------+
| 1 | 2016-01-01 08:00:00 | 2016-01-01 09:00:00 |
| 2 | 2016-01-01 09:30:00 | 2016-01-01 10:00:00 |
| 3 | 2016-01-01 13:00:00 | 2016-01-01 14:00:00 |
+------+---------------------+---------------------+
3 rows in set (0.00 sec)
感谢你的回答!我会尝试你的建议,并会让你知道它是否有效。:)嗨,Gordon,这个查询很有效,但它仍然提供所有的时钟输入和时钟输出,而不是我想要的最后输入和最后输出。但很高兴你给了我一些想法。它在SQL Fiddle中工作得非常完美,但在我本地的mysql中却不行。我编辑查询并将employee\u id=:employee\u id和datetime=:datetime放在其中。它给我所有的集合,每对中的一个都有空值。也许你应该问另一个问题。您的问题中没有employee\u id
,此答案似乎正确回答了您提出的问题。是。你的回答回答了我的问题。只是我没有在这里工作。我将尝试找出原因,也许需要改进代码以使其正常工作。非常感谢你的回答!:)感谢你的回答!我会尝试你的建议,并会让你知道它是否有效。:)嗨,Gordon,这个查询很有效,但它仍然提供所有的时钟输入和时钟输出,而不是我想要的最后输入和最后输出。但很高兴你给了我一些想法。它在SQL Fiddle中工作得非常完美,但在我本地的mysql中却不行。我编辑查询并将employee\u id=:employee\u id和datetime=:datetime放在其中。它给我所有的集合,每对中的一个都有空值。也许你应该问另一个问题。您的问题中没有employee\u id
,此答案似乎正确回答了您提出的问题。是。你的回答回答了我的问题。只是我没有在这里工作。我将尝试找出原因,也许需要改进代码以使其正常工作。非常感谢你的回答!:)这个答案很好用!非常感谢你!你救了我的命!这个答案很好用!非常感谢你!你救了我的命!
mysql> SELECT * FROM attendance;
+------+---------------------+------+
| Id | DateTime | Door |
+------+---------------------+------+
| 1 | 2016-01-01 08:00:00 | In |
| 2 | 2016-01-01 09:00:00 | Out |
| 3 | 2016-01-01 09:15:00 | In |
| 4 | 2016-01-01 09:30:00 | In |
| 5 | 2016-01-01 10:00:00 | Out |
| 6 | 2016-01-01 11:00:00 | In |
| 7 | 2016-01-01 12:00:00 | In |
| 8 | 2016-01-01 13:00:00 | In |
| 9 | 2016-01-01 13:30:00 | Out |
| 10 | 2016-01-01 14:00:00 | Out |
| 11 | 2016-01-01 15:00:00 | In |
+------+---------------------+------+
11 rows in set (0.00 sec)
mysql>
mysql> -- SQL needed:
mysql> SELECT
-> @id:=@id+1 Id,
-> MAX(IF(Door = 'In', DateTime, NULL)) `Check In`,
-> MAX(IF(Door = 'Out', DateTime, NULL)) `Check Out`
-> FROM
-> (SELECT
-> *,
-> CASE
-> WHEN
-> (door = 'In' AND @last_door = '') OR
-> (door = 'In' AND @last_door = 'In') OR
-> (door = 'Out' AND @last_door = 'In') OR
-> (door = 'Out' AND @last_door = 'Out')
-> THEN @group_num
-> WHEN
-> (door = 'In' AND @last_door = 'Out')
-> THEN @group_num:=@group_num+1
-> ELSE 0
-> END door_group,
-> @last_door:=Door
-> FROM attendance
-> JOIN (SELECT @group_num:=1) a
-> ) t JOIN (SELECT @id:=0) b
-> GROUP BY t.door_group
-> HAVING SUM(Door = 'In') > 0 AND SUM(Door = 'Out') > 0;
+------+---------------------+---------------------+
| Id | Check In | Check Out |
+------+---------------------+---------------------+
| 1 | 2016-01-01 08:00:00 | 2016-01-01 09:00:00 |
| 2 | 2016-01-01 09:30:00 | 2016-01-01 10:00:00 |
| 3 | 2016-01-01 13:00:00 | 2016-01-01 14:00:00 |
+------+---------------------+---------------------+
3 rows in set (0.00 sec)