В проекте БД видео, над которым я работаю, у каждого пользователя есть фид активности. Я хочу группировать подобные действия, например, как это делает Facebook, но немного отличается.
Например, если пользователь пишет обзор фильма, и через минуту он также голосует за этот фильм, а через 5 минут он загружает трейлер для этого фильма, я хочу показать его вместе (сгруппированный) в фиде активности.
Я думаю, что лучше всего группировать его при запросе базы данных, но я не думаю, что это возможно в этом случае, потому что я использую действительно большой JOIN для получения всех данных:
SELECT ua.datetime, ua.imdbID, ua.personID, sa.activityID, sa.activity, m.title, m.year, p.name, umv.vote, upv.vote, r.review, t.youTubeID, ps.filename, ph.filename FROM user_activity ua JOIN sys_activities sa ON ua.activityID = sa.activityID LEFT OUTER JOIN movies m ON ua.imdbID = m.imdbID LEFT OUTER JOIN persons p ON ua.personID = p.personID LEFT OUTER JOIN user_movies_vote umv ON umv.userID = ua.userID AND umv.imdbID = ua.imdbID LEFT OUTER JOIN user_persons_vote upv ON upv.userID = ua.userID AND upv.personID = ua.personID LEFT OUTER JOIN reviews r ON r.userID = ua.userID AND r.imdbID = ua.imdbID LEFT OUTER JOIN ( select imdbID, userID, youTubeID, max(hd) as MaxTrailerStatus from trailers group by imdbID ) t ON ua.imdbID = t.imdbID AND ua.userID = t.userID LEFT OUTER JOIN ( select imdbID, filename, max(main) as MaxPosterStatus from posters group by imdbID ) ps ON ua.imdbID = ps.imdbID LEFT OUTER JOIN ( select personID, filename, max(main) as MaxPhotosStatus from photos group by personID ) ph ON ua.personID = ph.personID WHERE ua.userID = ? ORDER BY ua.datetime DESC
Я хочу знать, как это сделать либо путем изменения запроса, либо с помощью PHP. Благодарю.
Вероятно, вы группируете идентификатор элемента изменяемого элемента, который в этом случае выглядит так: ua.imdbID.
Как только вы это сделаете, вы потеряете другие строки данных, поэтому вы должны использовать GROUP_CONCAT для получения всех связанных идентификаторов.
GROUP_CONCAT (sa.activityID);
Таким образом, ваш конечный результат:
SELECT ua.datetime, ua.imdbID, ua.personID, GROUP_CONCAT(sa.activityID), sa.activity, m.title, m.year, p.name, umv.vote, upv.vote, r.review, t.youTubeID, ps.filename, ph.filename FROM user_activity ua JOIN sys_activities sa ON ua.activityID = sa.activityID LEFT OUTER JOIN movies m ON ua.imdbID = m.imdbID LEFT OUTER JOIN persons p ON ua.personID = p.personID LEFT OUTER JOIN user_movies_vote umv ON umv.userID = ua.userID AND umv.imdbID = ua.imdbID LEFT OUTER JOIN user_persons_vote upv ON upv.userID = ua.userID AND upv.personID = ua.personID LEFT OUTER JOIN reviews r ON r.userID = ua.userID AND r.imdbID = ua.imdbID LEFT OUTER JOIN ( select imdbID, userID, youTubeID, max(hd) as MaxTrailerStatus from trailers group by imdbID ) t ON ua.imdbID = t.imdbID AND ua.userID = t.userID LEFT OUTER JOIN ( select imdbID, filename, max(main) as MaxPosterStatus from posters group by imdbID ) ps ON ua.imdbID = ps.imdbID LEFT OUTER JOIN ( select personID, filename, max(main) as MaxPhotosStatus from photos group by personID ) ph ON ua.personID = ph.personID WHERE ua.userID = ? GROUP BY ua.imdbID ORDER BY ua.datetime DESC