Ces avancées sont ce qui me fait aimer MySQL :)
SELECT user_id, user_name,
GROUP_CONCAT(CONVERT(photo_id, char(32)) ORDER BY photos.average_rate) as photo_ids
FROM ( SELECT user_id, user_name, photo_id, favorite_count, photo_count,
(case when @user_id = user_id then @rownum := @rownum + 1 else CONCAT(@rownum := 1, @user_id := user_id) end) AS dummy_val
FROM ( SELECT users.user_id, users.user_name, users.favorite_count, users.photo_count, photos.photo_id
FROM users
INNER JOIN photos
ON photos.user_id=users.user_id
WHERE users.day_of_birth = DATE_FORMAT('2012-04-17', '%m-%d')
AND users.photo_count > 0
ORDER BY users.id ASC, photos.average_rate ASC
) AS h,
( @rownum := NULL,
@user_id := NULL
) AS vars
HAVING rownum <= 5) AS h2
GROUP BY user_id
ORDER BY favorite_count DESC, photo_count DESC LIMIT 0, 10
En gros, j'obtiens toutes les lignes et je jette toutes les photos dont le nombre de lignes calculé est supérieur ou égal à 6.