如何 select 每个设备用户的最后一条消息
How to select last message by user per device
我已经处理这个查询很长时间了,但没有解决方案。
我有这个table:
user_id | device | message | timestamp
|---------|---------|---------|----------------------|
| 1 | android | hi | 2018-06-01T00:00:00Z |
| 1 | ios | hello | 2018-06-02T00:00:00Z |
| 1 | android | hey | 2018-06-03T00:00:00Z |
| 2 | android | asdasd | 2018-06-14T00:00:00Z |
| 3 | android | good | 2018-06-03T00:00:00Z |
| 3 | ios | great | 2018-06-04T00:00:00Z |
| 3 | ios | awesome | 2018-06-11T00:00:00Z |
| 4 | ios | yes | 2018-06-02T00:00:00Z |
| 4 | ios | yeah | 2018-06-03T00:00:00Z |
| 5 | ios | no | 2018-06-22T00:00:00Z |
| 5 | android | nah | 2018-06-23T00:00:00Z |
如何获取用户每台设备的最后一条消息?
因此,对于用户 3,我会得到:
| 3 | android | good | 2018-06-03T00:00:00Z |
| 3 | ios | awesome | 2018-06-11T00:00:00Z |
您需要编写一个子查询以通过 user_id
和 device
获取 max
timestamp
然后 self join
SELECT t1.user_id,t1.device,t1.message,t.timestamp
FROM (
SELECT user_id,device,max(timestamp) timestamp
FROM T
GROUP BY user_id,device
) t INNER JOIN T t1 on t.user_id = t1.user_id AND t.timestamp = t1.timestamp
WHERE t1.user_id = 3
结果
| user_id | device | message | timestamp |
|---------|---------|---------|----------------------|
| 3 | android | good | 2018-06-03T00:00:00Z |
| 3 | ios | awesome | 2018-06-11T00:00:00Z |
你应该使用相关的子查询来编写:
select t.*
from t
where t.user_id = 3 and
t.timestamp = (select max(t2.timestamp)
from t t2
where t2.user_id = t.user_id and
t2.device = t.device
);
对于此查询,您需要 (user_id, device, timestamp)
上的索引。
性能应该比group by
版本好很多,因为没有聚合整个table。
只需按时间戳对 desc 中的 table 进行排序,然后按 user_id 和设备对其进行分组。
select * from (
select * from Table t order by timestamp desc)a
group by user_id, device ;
我已经处理这个查询很长时间了,但没有解决方案。
我有这个table:
user_id | device | message | timestamp
|---------|---------|---------|----------------------|
| 1 | android | hi | 2018-06-01T00:00:00Z |
| 1 | ios | hello | 2018-06-02T00:00:00Z |
| 1 | android | hey | 2018-06-03T00:00:00Z |
| 2 | android | asdasd | 2018-06-14T00:00:00Z |
| 3 | android | good | 2018-06-03T00:00:00Z |
| 3 | ios | great | 2018-06-04T00:00:00Z |
| 3 | ios | awesome | 2018-06-11T00:00:00Z |
| 4 | ios | yes | 2018-06-02T00:00:00Z |
| 4 | ios | yeah | 2018-06-03T00:00:00Z |
| 5 | ios | no | 2018-06-22T00:00:00Z |
| 5 | android | nah | 2018-06-23T00:00:00Z |
如何获取用户每台设备的最后一条消息?
因此,对于用户 3,我会得到:
| 3 | android | good | 2018-06-03T00:00:00Z |
| 3 | ios | awesome | 2018-06-11T00:00:00Z |
您需要编写一个子查询以通过 user_id
和 device
获取 max
timestamp
然后 self join
SELECT t1.user_id,t1.device,t1.message,t.timestamp
FROM (
SELECT user_id,device,max(timestamp) timestamp
FROM T
GROUP BY user_id,device
) t INNER JOIN T t1 on t.user_id = t1.user_id AND t.timestamp = t1.timestamp
WHERE t1.user_id = 3
结果
| user_id | device | message | timestamp |
|---------|---------|---------|----------------------|
| 3 | android | good | 2018-06-03T00:00:00Z |
| 3 | ios | awesome | 2018-06-11T00:00:00Z |
你应该使用相关的子查询来编写:
select t.*
from t
where t.user_id = 3 and
t.timestamp = (select max(t2.timestamp)
from t t2
where t2.user_id = t.user_id and
t2.device = t.device
);
对于此查询,您需要 (user_id, device, timestamp)
上的索引。
性能应该比group by
版本好很多,因为没有聚合整个table。
只需按时间戳对 desc 中的 table 进行排序,然后按 user_id 和设备对其进行分组。
select * from (
select * from Table t order by timestamp desc)a
group by user_id, device ;