Предположим, что мы ищем оценки пользователя с id = 1 (просто для проверки запроса без php).
Вы можете заменить его на $ Id позже.
Если ваш столбец дат достаточно точен, чтобы обеспечить его уникальность для каждой оценки, которую вы можете использовать:
SELECT s.section_name, g1.grade FROM
( SELECT g.section_id, max(g.date) AS last_grade_date
FROM grades g
WHERE g.user_id = 1
GROUP BY g.section_id ) gd
JOIN grades g1
ON g1.date = gd.last_grade_date
JOIN sections s
ON s.id = gd.section_id
Если ваша дата не уникальна, вы должны присоединить оценки к себе по идентификатору, найденному в зависимом подзапросе:
SELECT s.section_name, ga.grade FROM
( SELECT g1.section_id, max(g1.date) AS last_grade_date
FROM grades g1
WHERE g1.user_id = 1
GROUP BY g1.section_id ) gmax
JOIN grades ga
ON ga.id =
( SELECT g2.id
FROM grades g2
WHERE g2.user_id = 1
AND g2.section_id = gmax.section_id
AND g2.date = gmax.last_grade_date
LIMIT 1 )
JOIN sections s
ON s.id = gmax.section_id
Для этого запроса необходим индекс (user_id, section_id, date).
ALTER TABLE grades ADD INDEX user_section_date( user_id, section_id, date ) ;
@ Комментарий:
Хорошо, я попытаюсь объяснить второй запрос, поскольку он дает правильные результаты для любого случая.
В таблице g1 мы берем строки из оценок для пользователя с id = 1, мы группируем их по разделам и в каждом разделе мы находим максимальную дату - что означает самую последнюю дату. На данный момент мы еще не знаем, какая строка в точности содержит эту самую последнюю дату, потому что мы можем выбрать только столбцы, которые находятся в group by
или в агрегатных функциях (например, max ()). Mysql позволяет выбирать другие столбцы, такие как класс, называемые скрытыми столбцами (другие dbs просто выдают синтаксическую ошибку), но он может возвращать любую строку из каждой группы, обычно не ту, которую мы хотим, и мы хотим, чтобы та содержала самую последнюю Дата. Если все строки имеют одинаковое значение, как, например, user_id в этом случае, это нормально, но нам нужны оценки, которые могут быть разными в каждой группе. Для небольших таблиц select может вернуть правильную, поэтому некоторые люди утверждают, что упорядочение по дате может помочь, потому что они проверяют его на небольших таблицах и видят правильные результаты, но это происходит неправильно, когда таблица увеличивается, появляются обновления строк, удаления и т.д. на.
По сути, теперь у нас есть список разделов и самых последних дат, и нам нужно выяснить оценки. Таким образом, мы должны присоединиться к этой таблице g1, которую мы только что получили в таблицу оценок, чтобы найти строку, которая содержит самую последнюю дату для каждого раздела. Идентификатор - единственный столбец, мы уверены, что он уникален (если мы не объединяем уникальный столбец или уникальный список столбцов, мы получим больше строк, и нам нужен ровно один), поэтому мы пытаемся найти этот идентификатор в зависимом подзапросе g2 ( это подзапрос, который ссылается на значения извне, в данном случае из gmax, который является псевдонимом для g1, объясненного ранее).
Как только у нас есть оценка для каждого section_id, остается только присоединить его к таблице разделов section_id, чтобы получить section_name вместо его значения id.