检索具有相同值的重复序列中的最后一条记录

时间:2017-05-24 18:43:12

标签: mysql sql

任何人都可以帮助我:

记录来自考勤跟踪软件。 任何员工都可能在不同的读者身上不止一次地登记或结账,甚至更糟(前3行)。 入口:1101,1102。出口:101,102。

SELECT * FROM `attendance` WHERE ATUserID = 856 AND (ATReaderID = 101 OR ATReaderID = 102 OR ATReaderID = 1101 OR ATReaderID = 1102);
+--------+------------+----------+----------+------------+
| ATid   | ATDate     | ATTime   | ATUserID | ATReaderID |
+--------+------------+----------+----------+------------+
| 403396 | 2017-05-08 | 07:55:20 |      856 |       1102 |
| 403399 | 2017-05-08 | 07:55:22 |      856 |       1102 |
| 403450 | 2017-05-08 | 07:55:40 |      856 |       1101 |
| 407934 | 2017-05-08 | 16:11:40 |      856 |        102 |
| 407940 | 2017-05-08 | 16:11:45 |      856 |        102 |
| 409990 | 2017-05-09 | 07:56:35 |      856 |       1102 |
| 411490 | 2017-05-09 | 07:56:40 |      856 |       1102 |
| 413525 | 2017-05-09 | 15:59:40 |      856 |        102 |
| 413583 | 2017-05-09 | 15:59:52 |      856 |        102 |
| 413603 | 2017-05-10 | 07:54:50 |      856 |       1101 |
| 422315 | 2017-05-10 | 16:01:00 |      856 |        101 |
+--------+------------+----------+----------+------------+

我想只获得每个序列中的最后一个事件(ATReaderID):

+--------+------------+----------+----------+------------+
| ATid   | ATDate     | ATTime   | ATUserID | ATReaderID |
+--------+------------+----------+----------+------------+
| 403450 | 2017-05-08 | 07:55:40 |      856 |       1101 |
| 407940 | 2017-05-08 | 16:11:45 |      856 |        102 |
| 411490 | 2017-05-09 | 07:56:40 |      856 |       1102 |
| 413583 | 2017-05-09 | 15:59:52 |      856 |        102 |
| 413603 | 2017-05-10 | 07:54:50 |      856 |       1101 |
| 422315 | 2017-05-10 | 16:01:00 |      856 |        101 |
+--------+------------+----------+----------+------------+

由于夜班(今天入口/明天退出),并且每天允许多次入口/出口,不能依赖日期栏(每天的最后入口和出口)。

尝试使用此解决方案Retrieving the last record in each group进行锻炼,但未成功。

1 个答案:

答案 0 :(得分:0)

使用变量将下一条记录的阅读器类型与当前:

进行比较
select
  atid, atdate, attime, atuserid, atreaderid
from
(
  select 
    atid, atdate, attime, atuserid, atreaderid, 
    (atreaderid div 1000 <> @after div 1000) as keepit,
    @after := atreaderid
  from attendance
  cross join (select @after := 2000) var
  where atuserid = 856 and atreaderid in (101, 102, 1101, 1102)
  order by timestamp(atdate, attime) desc, atid desc
) marked
where keepit
order by timestamp(atdate, attime), atid;

演示:http://rextester.com/ZCPUB70643