У меня есть следующая таблица в MySQL:
+-----------+------------+------------+------+-----------+
| user_name | session_id | status | data | timestamp |
+-----------+------------+------------+------+-----------+
| foo | 1 | start | 0 | 100 |
| foo | 1 | checkpoint | 15 | 120 |
| foo | 1 | stop | 46 | 130 |
| foo | 2 | start | 0 | 200 |
| foo | 2 | checkpoint | 97 | 210 |
+-----------+------------+------------+------+-----------+
Я пытаюсь выполнить запрос, который выбирает все поля из таблицы, сгруппированные по session_id, и результат которого отображается для одной группы какстрока с самой большой отметкой времени.
Вот что я придумала, она не выполняет свою работу, и я изо всех сил пытаюсь найти, куда идти отсюда:
select * from example where user_name = 'foo' and timestamp > 10 group by acct_session_id;
Этот оператор производит что-то вроде следующего:
+-----------+------------+------------+------+-----------+
| user_name | session_id | status | data | timestamp |
+-----------+------------+------------+------+-----------+
| foo | 1 | checkpoint | 15 | 120 |
| foo | 2 | start | 0 | 200 |
+-----------+------------+------------+------+-----------+
То, что я хотел бы получить в результате:
+-----------+------------+------------+------+-----------+
| user_name | session_id | status | data | timestamp |
+-----------+------------+------------+------+-----------+
| foo | 1 | stop | 46 | 130 |
| foo | 2 | checkpoint | 97 | 210 |
+-----------+------------+------------+------+-----------+
В этом примере строка с наибольшей отметкой времени была возвращена как 'top 'of the group.
Также, за любые предоставленные ответы, я был бы очень признателен за любые предложения относительно правильного индекса, чтобы этот оператор выполнялся максимально быстро.Я всегда пытался найти правильный индекс для сложного запроса, такого как этот.
* РЕДАКТИРОВАТЬ
Я прочитал ответы, найденные в теме, что эта тема была отмечена как дубликати попытался приспособить их к моему вопросу, но безуспешно.
Сначала я попробовал основной ответ из связанной ветки, изменив идентификаторы, чтобы они соответствовали моей таблице:
WITH ranked_messages AS (
SELECT e.*, ROW_NUMBER() OVER (PARTITION BY session_id ORDER BY timestamp DESC) AS rn
FROM example AS e
)
SELECT * FROM ranked_messages WHERE rn = 1;
Я не имел успеха с этим, и в этот момент я очень смущен тем, что делает заявление.Итак, затем я посмотрел документацию для оконных функций здесь: https://dev.mysql.com/doc/refman/8.0/en/window-functions-usage.html
Чтение этого не помогло так сильно, как я надеялся, но я вернулся к связанному потоку и попробовал несколько вещей.
Это самое близкое, что я получил:
SELECT e1.*
FROM example e1 LEFT JOIN example e2
ON (e1.session_id = e2.session_id AND e1.timestamp < e2.timestamp)
WHERE e2.timestamp IS NULL and e1.user_name = 'foo';
В моей маленькой тестовой таблице это дало ожидаемый ответ, однако у меня только одно имя пользователя в этой таблице.Я не могу понять, как изменить этот запрос, чтобы искать только определенное имя пользователя, ДО того, как оно выполнит СЛЕДУЮЩЕЕ СОЕДИНЕНИЕ, потому что в моей рабочей таблице у меня есть миллионы строк и тысячи имен пользователей, и я не могу выполнить этот запрос для каждого пользователя каждый раз.