Mysql在指定的时间范围内按用户ID获取上次更新

时间:2012-11-29 01:37:17

标签: php mysql greatest-n-per-group

我有两个表tc_users和tc_timeclock。我想获取每个活动用户的当前状态。但只有那些在过去12小时内进行了更新(进入或退出)的人。我已经知道如何在过去12小时内获取所有更新,但不知道如何将其缩小到每个用户的最后一个更新。

以下是我的表格:

tc_users:

user_id | first_name | last_name | active
-----------------------------------------
1 | Frank   | Zappa     | 1
2 | John    | Mcneely   | 1
3 | Bill    | Mckenna   | 1
4 | Mark    | langdon   | 1
5 | Steve   | Mcalister | 0
6 | William | Stevens   | 1
7 | John    | Jones     | 0

tc_timeclock:

tc_id | user_id | status | time_stamp
-------------------------------------
1  | 1 | IN  | 2012-11-28 09:00:25
2  | 2 | IN  | 2012-11-28 09:01:25
3  | 3 | IN  | 2012-11-26 09:03:25
4  | 4 | IN  | 2012-11-28 09:21:25
5  | 5 | IN  | 2012-11-28 09:01:12
6  | 6 | IN  | 2012-11-28 09:47:13
7  | 7 | IN  | 2012-11-12 09:00:22
8  | 7 | OUT | 2012-11-12 09:03:28
9  | 5 | OUT | 2012-11-28 09:21:25
10 | 6 | OUT | 2012-11-28 11:47:13
11 | 3 | OUT | 2012-11-26 11:03:25
12 | 2 | OUT | 2012-11-28 11:01:25
13 | 1 | OUT | 2012-11-28 11:27:25
14 | 4 | OUT | 2012-11-28 11:21:25
15 | 4 | IN  | 2012-11-28 12:21:25
16 | 1 | IN  | 2012-11-28 12:27:25
17 | 3 | IN  | 2012-11-26 12:03:25
18 | 6 | IN  | 2012-11-28 12:47:13
19 | 2 | IN  | 2012-11-28 12:01:25
20 | 1 | OUT | 2012-11-28 17:27:25
21 | 4 | OUT | 2012-11-28 17:21:25
22 | 3 | OUT | 2012-11-26 17:03:25
23 | 2 | OUT | 2012-11-28 17:01:25

到目前为止这是我提出的查询:

如果现在= 2012-11-28 18:00:00

SELECT first_name, last_name, status, time_stamp 
FROM tc_timeclock 
  INNER JOIN tc_users 
    ON tc_timeclock.user_id = tc_users.user_id 
WHERE tc_users.active = 1 
  AND tc_timeclock.time_stamp BETWEEN '2012-11-28 06:00:00' AND '2012-11-28 18:00:00' 

这会显示过去12小时内的所有内容,如下所示:

first_name | last_name | status | time_stamp
-----------------------------------------------------
Frank      | Zappa     | IN     | 2012-11-28 09:00:25
John       | Mcneely   | IN     | 2012-11-28 09:01:25
Mark       | langdon   | IN     | 2012-11-28 09:21:25
William    | Stevens   | IN     | 2012-11-28 09:47:13
William    | Stevens   | OUT    | 2012-11-28 11:47:13
John       | Mcneely   | OUT    | 2012-11-28 11:01:25
Frank      | Zappa     | OUT    | 2012-11-28 11:27:25
Mark       | langdon   | OUT    | 2012-11-28 11:21:25
Mark       | langdon   | IN     | 2012-11-28 12:21:25
Frank      | Zappa     | IN     | 2012-11-28 12:27:25
William    | Stevens   | IN     | 2012-11-28 12:47:13
John       | Mcneely   | IN     | 2012-11-28 12:01:25
Frank      | Zappa     | OUT    | 2012-11-28 17:27:25
Mark       | langdon   | OUT    | 2012-11-28 17:21:25
John       | Mcneely   | OUT    | 2012-11-28 17:01:25

我正在寻找的逻辑: 获取在过去12小时内为每个活动用户记录状态的名字,姓氏,当前状态和时间。

所以输出应该是:

first_name | last_name | status | time_stamp
Frank      | Zappa     | OUT    | 2012-11-28 17:27:25
John       | Mcneely   | OUT    | 2012-11-28 17:01:25
Mark       | langdon   | OUT    | 2012-11-28 17:21:25
William    | Stevens   | IN     | 2012-11-28 12:47:13

用户5(Steve Mcalister)和7(John Jones)未激活,因此不会显示。

用户3(Bill Mckenna)在过去12小时内没有任何活动,所以他也没有任何活动。

我错过了一些非常简单的事情吗? (我相信我是)

如果没有简单的解决方案,我可以解决这个问题,我总是可以在tc_users表中添加两列:(tc_users.current_status和tc_users.status_time)并简单地将它们与tc_timeclock中的最后一个条目相同表。

这样我可以很容易地选择它们,我不喜欢让数据变得多余的想法,如果我不需要的话。

2 个答案:

答案 0 :(得分:1)

这样的事可能适合你。

SQL:

SELECT `tc_users`.`first_name`, `tc_users`.`last_name`, `tc_timeclock`.`status`, `temp_table`.`last_updated`
  FROM `tc_users`
 INNER JOIN `tc_timeclock`
         ON `tc_users`.`user_id`=`tc_timeclock`.`user_id`
 INNER JOIN (
             SELECT `user_id`, MAX(`time_stamp`) AS `last_updated` FROM `tc_timeclock` GROUP BY `user_id`
            ) AS `temp_table`
         ON `tc_users`.`user_id`=`temp_table`.`user_id`
        AND `tc_timeclock`.`time_stamp`=`temp_table`.`last_updated`
 WHERE `tc_users`.`active`!=0
   AND `temp_table`.`last_updated`>(NOW() - INTERVAL 12 HOUR);

OUT:

+------------+-----------+--------+---------------------+
| first_name | last_name | status | last_updated        |
+------------+-----------+--------+---------------------+
| William    | Stevens   | IN     | 2012-11-28 12:47:13 |
| Frank      | Zappa     | OUT    | 2012-11-28 17:27:25 |
| Mark       | langdon   | OUT    | 2012-11-28 17:21:25 |
| John       | Mcneely   | OUT    | 2012-11-28 17:01:25 |
+------------+-----------+--------+---------------------+

HTH

答案 1 :(得分:0)

查询:

<强> SQLFIDDLEExample

SELECT first_name, last_name, tml.status, tml.time_stamp 
FROM (SELECT * 
      FROM tc_timeclock tl
      WHERE tl.time_stamp = (SELECT MAX(time_stamp) 
                             FROM tc_timeclock
                             WHERE tl.user_id = user_id )) tml
  INNER JOIN tc_users 
    ON tml.user_id = tc_users.user_id 
WHERE tc_users.active = 1 
  AND tml.time_stamp BETWEEN '2012-11-28 06:00:00' AND '2012-11-28 18:00:00' 

结果:

| FIRST_NAME | LAST_NAME | STATUS |                      TIME_STAMP |
---------------------------------------------------------------------
|      Frank |     Zappa |    OUT | November, 28 2012 17:27:25+0000 |
|       John |   Mcneely |    OUT | November, 28 2012 17:01:25+0000 |
|       Mark |   langdon |    OUT | November, 28 2012 17:21:25+0000 |
|    William |   Stevens |     IN | November, 28 2012 12:47:13+0000 |