如何 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_iddevice 获取 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

sqlfiddle


结果

| 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 ;