如何按用户按设备选择最后一条消息

时间:2018-07-03 21:54:46

标签: mysql sql group-by sql-order-by

我已经解决这个查询已有相当长的一段时间了。

我有这张桌子:

  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 |

3 个答案:

答案 0 :(得分:1)

您需要编写一个子查询,以通过maxtimestamp然后user_id来获得device 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 |

答案 1 :(得分:0)

您应该使用相关子查询来编写它:

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版本好得多,因为不会汇总整个表。

答案 2 :(得分:0)

只需按时间戳在desc中对表进行排序,并按user_id和设备将其分组。

RPCException