myślę, że to rozwiązałem :)
Najpierw jest jedno rozwiązanie oparte na sposobie, w jaki zacząłeś. Ale jest haczyk, którego nie mogłem rozwiązać, aby pokazać dokładnie 3 (lub dowolną liczbę, którą wybrałeś, na przykład wybrałem 3) dla każdego person_id. Problem polega na tym, że rozwiązanie polega na zliczeniu liczby wierszy o wartości rating_average większej niż bieżący wiersz. Więc jeśli masz 5 takich samych najwyższej wartości, możesz wybrać pokazanie wszystkich 5 lub nie pokazywać ich w ogóle, a to nie jest dobre. Oto sposób, w jaki to robisz... (oczywiście jest to przykład, w którym jeśli masz 4 najwyższe wartości, pokazujesz je wszystkie (myślę, że nie ma sensu nie pokazywać danych))...
SELECT t1.person_id, t1.credit_id, t1.media_id, t1.rating_average
FROM (SELECT p.id AS person_id, c.id AS credit_id, m.id AS media_id,
m.rating_average AS rating_average
FROM person p
INNER JOIN credit c ON c.person_id = p.id
INNER JOIN media m ON m.id = c.media_id) as t1
WHERE (SELECT COUNT(*)
FROM (SELECT p.id AS person_id, c.id AS credit_id, m.id AS media_id,
m.rating_average AS rating_average
FROM person p
INNER JOIN credit c ON c.person_id = p.id
INNER JOIN media m ON m.id = c.media_id) AS t2
WHERE t2.person_id = t1.person_id AND t2.rating_average > t1.rating_average) < 3
ORDER BY person_id ASC, rating_average DESC
Ważne: To rozwiązanie może zadziałać (aby pokazać dokładnie 3 wiersze dla każdej osoby), jeśli nie masz wartości, która się powtarza... Oto Fiddle http://sqlfiddle.com/#!9/eb0fd/64 widać problem, gdzie person_id wynosi 1!
Potem grałem trochę więcej i sprawiłem, że działało tak, jak chciałeś w pytaniu, jak sądzę. Oto kod do tego:
SET @num := 0, @person := 0;
SELECT person_id, credit_id, media_id, rating_average, rowNumber
FROM (SELECT t1.person_id, t1.credit_id, t1.media_id, t1.rating_average,
@num := if(@person = t1.person_id, @num + 1, 1) AS rowNumber,
@person := t1.person_id
FROM (SELECT p.id AS person_id, c.id AS credit_id, m.id AS media_id,
m.rating_average AS rating_average
FROM person p
INNER JOIN credit c ON c.person_id = p.id
INNER JOIN media m ON m.id = c.media_id
ORDER BY p.id ASC, m.rating_average DESC) as t1) as t2
WHERE rowNumber <= 3
Oto Fiddle dla tego http://sqlfiddle.com/#!9/eb0fd/65 ...
GL!
P. S. przepraszam za moją angielską nadzieję, że zrozumiesz, o czym mówię...