Mysql
 sql >> Base de données >  >> RDS >> Mysql

MySQL Greatest N Results avec Join Tables

je pense que je l'ai résolu :)

Voici d'abord une solution basée sur la façon dont vous avez commencé. Mais il y a un problème que je n'ai pas pu résoudre pour afficher exactement 3 lignes (ou quel que soit le nombre que vous choisissez, je choisis 3 par exemple) pour chaque person_id. Le problème est que la solution est basée sur le comptage du nombre de lignes avec le rating_average supérieur à la ligne actuelle. Donc, si vous avez 5 mêmes valeurs maximales, vous pouvez choisir d'afficher les 5 ou de ne pas les afficher du tout et ce n'est pas bon. Voici donc comment procéder... (bien sûr, c'est un exemple où si vous avez 4 valeurs supérieures, vous les affichez toutes (je pense que cela n'a aucun sens de ne pas afficher les données))...

 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

Important : Cette solution peut fonctionner (pour afficher exactement 3 lignes pour chaque personne) si vous n'avez pas de valeur qui se répète... Voici le Fiddle http://sqlfiddle.com/#!9/eb0fd/64 vous pouvez voir le problème où person_id vaut 1 !

Après cela, j'ai joué un peu plus et je l'ai fait fonctionner comme vous le vouliez dans la question, je pense. Voici un code pour cela :

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

Voici le violon pour cela http://sqlfiddle.com/#!9/eb0fd/65 ...

GL !

P. S. désolé pour mon anglais, j'espère que vous avez compris de quoi je parlais...