MySQL过滤每个项目的最后一个用户的第一个日期

时间:2014-03-13 09:12:49

标签: mysql

我遇到了这个问题,我已经挣扎了一段时间。

我有这些数据:

+----+---------+---------+---------------------+
| id | file_id | user_id | action_datetime     |
+----+---------+---------+---------------------+
|  1 |       1 |       2 | 2014-03-13 13:39:31 |
|  2 |       1 |       2 | 2014-03-13 13:39:43 |
|  3 |       1 |       1 | 2014-03-13 13:59:34 |
|  4 |       1 |       1 | 2014-03-13 14:01:38 |
|  5 |       1 |       1 | 2014-03-13 14:03:12 |
|  6 |       2 |       2 | 2014-03-13 14:04:51 |
|  7 |       2 |       2 | 2014-03-13 14:07:37 |
|  8 |       1 |       1 | 2014-03-13 14:08:04 |
|  9 |       3 |       1 | 2014-03-13 14:08:09 |
| 10 |       3 |       1 | 2014-03-13 14:08:12 |
| 11 |       4 |       1 | 2014-03-13 14:08:14 |
| 12 |       4 |       1 | 2014-03-13 14:08:16 |
| 13 |       5 |       1 | 2014-03-13 14:08:26 |
| 14 |       1 |       1 | 2014-03-13 14:08:40 |
| 15 |       2 |       2 | 2014-03-13 14:09:13 |
+----+---------+---------+---------------------+

我需要为每个文件选择具有最后一个用户的第一个日期的行,即我需要的行是:

+----+---------+---------+---------------------+
| id | file_id | user_id | action_datetime     |
+----+---------+---------+---------------------+
|  3 |       1 |       1 | 2014-03-13 13:59:34 |
|  6 |       2 |       2 | 2014-03-13 14:04:51 |
|  9 |       3 |       1 | 2014-03-13 14:08:09 |
| 11 |       4 |       1 | 2014-03-13 14:08:14 |
| 13 |       5 |       1 | 2014-03-13 14:08:26 |
+----+---------+---------+---------------------+

我在下面的查询中尝试了一些事情,但我知道它并不好。请帮忙。

SELECT
t1.id as id,
t1.file_id as file_id,
t1.user_id as user_id,
t1.action_datetime as datetime
FROM `table_1` as t1 
WHERE t1.`id` IN (SELECT MIN(id) FROM `table_1` GROUP BY `file_id`) 

SQL小提琴HERE

提前致谢。

2 个答案:

答案 0 :(得分:1)

你走了:

SELECT t.* FROM (
  SELECT t2.`file_id`, t2.`user_id`, MIN(t2.`action_datetime`) ts_first_date FROM (
    SELECT t1.*
    FROM table_1 t1
    JOIN (
      SELECT `file_id`, MAX(`action_datetime`) as ts_last_user
      FROM table_1
      GROUP BY `file_id`
    ) tmp2
    ON tmp2.`file_id` = t1.`file_id` AND tmp2.ts_last_user = t1.action_datetime
  ) t3
  JOIN table_1 t2
  ON t3.`file_id` = t2.`file_id` AND t3.`user_id` = t2.`user_id`
  GROUP BY t2.`file_id`, t2.`user_id`
) outertable
JOIN
table_1 t
ON t.user_id = outertable.user_id AND t.file_id = outertable.file_id AND t.action_datetime = outertable.ts_first_date
ORDER BY t.file_id

我知道它很难理解但仍然有效:)

工作小提琴:http://sqlfiddle.com/#!2/ba935f/105

最内部联接用于查找file_id和user_id对,以获取文件上最后一位用户的对象。然后在其他联接中使用此对来获取此特定组的第一个访问日期。

答案 1 :(得分:-2)

同意 G one 的评论,您所需输出中的第一行应为user_id=2 action_datetime=2014-03-13 13:39:31,否则似乎没有意义。 (或者你没有说出你的问题,以便我们能够正确理解它。)

要做到这一点,您可以使用MySQL手册中描述的方法The Rows Holding the Group-wise Maximum of a Certain Column

SELECT
    t1.id AS id,
    t1.file_id AS file_id,
    t1.user_id AS user_id,
    t1.action_datetime AS datetime
FROM table_1 AS t1
LEFT JOIN table_1 t2
  ON t1.file_id = t2.file_id
  AND t1.action_datetime > t2.action_datetime
WHERE t2.id IS NULL;

http://sqlfiddle.com/#!2/ba935f/62

编辑:好的,如果你真的希望第3行基于它是“最后一个用户的第一个日期”,那么你必须将这种方法应用两次,相互嵌套:首先得到最后一个用户的ID,然后再根据文件和用户的组合获得最小日期。