У меня есть MySQL таблицы, как это, и я хотел бы вычислить TOP10 для каждого жанра:MySQL сумма рейтинга, группа по жанру, ограничение 10
- rankings_2016 (TrackID, genreId, рейтинг, метка времени)
- жанры (genreId, genreName)
- дорожки (TrackID, trackName, genreId)
- художников (artistId, artistName)
- artists_tracks (artistId, TrackID)
Я бы хотел получить рейтинг TOP10 для каждого жанра, для каждого трека и для каждого исполнителя.
Дорожка или художник могут иметь до 2-х жанров. Ранжирование может быть одинаковым. Просто, чтобы получить представление с LIMIT 2:
genreId | trackId | ranking
---------------------------------
0 1111 100
0 2222 99
1 1111 100
1 2222 99
genreId | artistId | ranking
---------------------------------
0 1111 100
0 2222 99
1 1111 100
1 2222 99
Единственное решение, которое я нашел становится все в таблице, а затем LIMIT 10 на странице, но это убивает мою базу данных с точки зрения размера (я ограниченные ресурсы) ,
Для треков я написал:
SELECT trackId, genreId, @newRank := SUM(ranking) as ranking
FROM rankings_2016
WHERE timestamp >= (select unix_timestamp('2016-01-01'))
AND timestamp <= (select unix_timestamp('2016-12-31'))
GROUP BY trackId, genreId
Для художников:
SELECT artistId, genreId, @newRank := SUM(a1.ranking) as ranking
FROM rankings_2016 a1
LEFT JOIN artists_tracks a2
ON a1.trackId = a2.trackId
WHERE timestamp >= (select unix_timestamp('2016-01-01'))
AND timestamp <= (select unix_timestamp('2016-12-31'))
GROUP BY artistId, genreId
благодарственное все заранее для ваших подсказок.
UPDATE
Логика в целом (и принят ответ) требует хороших индексов и производительную сервера.
ARTISTS в моем случае не удалось с ошибкой 500, если я не увеличил процессор. В общем случае замена LEFT на INNER экономит 1 секунду.
Если производительность является проблемой и ранжирование не изменяется часто, рассмотрите предварительный расчет ответа. – alttag
Рейтинги ежедневно меняются: мои фактические запросы предварительно заполняют некоторые таблицы, при этом все результаты тратят сотни тысяч строк в день. Как я могу ограничить до 20 непосредственно на стадии предварительного заполнения? – fab
Убедитесь, что у вас есть указатель на таблице «timestamp». Не могу придумать ничего, что могло бы замедлить эти простые запросы. – Barmar