Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Maiores N resultados do MySQL com tabelas de junção


acho que resolvo :)

Primeiro, aqui está uma solução baseada na maneira como você começou. Mas há um problema que não consegui resolver para mostrar exatamente 3 (ou qualquer número que você escolher, eu escolho 3, por exemplo) para cada pessoa_id. O problema é que a solução é baseada na contagem de quantas linhas existem com o rating_average maior que a linha atual. Então, se você tiver 5 valores iguais, você pode optar por mostrar todos os 5 ou não mostrá-los e isso não é bom. Então aqui está a maneira de fazer isso ... (é claro que este é um exemplo em que se você tiver 4 valores superiores, você mostra todos eles (acho que não faz sentido não mostrar os dados)) ...
 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

Importante: Esta solução pode funcionar (para mostrar exatamente 3 linhas para cada pessoa) se você não tiver um valor que se repita... Aqui está o Fiddle http://sqlfiddle.com/#!9/eb0fd/64 você pode ver o problema onde person_id é 1!

Depois disso eu joguei um pouco mais e fiz funcionar como você queria na pergunta eu acho. Aqui está um código para isso:
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

Aqui está o violino para isso http://sqlfiddle.com/#!9/eb0fd/65 ...

GL!

P. S. desculpe pelo meu inglês espero que você tenha entendido o que eu estava falando...