Как выбрать последнее сообщение по пользователю для каждого устройства - PullRequest
0 голосов
/ 04 июля 2018

Я довольно долго занимался этим вопросом без решения.

У меня есть эта таблица:

  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 голосов
/ 04 июля 2018

Вы должны написать это, используя коррелированный подзапрос:

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, поскольку вся таблица не агрегируется.

0 голосов
/ 04 июля 2018

Просто закажите таблицу в desc по отметке времени и сгруппируйте ее по user_id & device.

select * from (
select * from Table t order by timestamp desc)a 
group by user_id, device ;
0 голосов
/ 04 июля 2018

Вам нужно написать подзапрос, чтобы получить max timestamp на 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 |
...