Mysql
 sql >> Database >  >> RDS >> Mysql

MySQL Greatest N risultati con join tabelle

penso di risolverlo :)

Per prima cosa, ecco una soluzione basata sul modo in cui hai iniziato. Ma c'è un problema che non sono riuscito a risolvere per mostrare 3 righe esatte (o qualunque numero tu scelga, ad esempio scelgo 3) per ogni person_id. Il problema è che la soluzione si basa sul conteggio di quante righe ci sono con rating_average maggiore della riga corrente. Quindi, se hai 5 stesso valore massimo, puoi scegliere di mostrarli tutti e 5 o di non mostrarli affatto e non va bene. Quindi ecco il modo in cui lo fai... (ovviamente questo è un esempio in cui se hai 4 valori massimi li mostri tutti (penso che non abbia affatto senso non mostrare i dati)))...

 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: Questa soluzione può funzionare (per mostrare 3 righe esatte per ogni persona) se non hai un valore che si ripete da solo... Ecco il Fiddle http://sqlfiddle.com/#!9/eb0fd/64 puoi vedere il problema dove person_id è 1!

Dopodiché ho giocato un po' di più e l'ho fatto funzionare proprio come volevi nella domanda, penso. Ecco un codice per questo:

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

Ecco il violino per quel http://sqlfiddle.com/#!9/eb0fd/65 ...

Gl!

P.S. scusa per il mio inglese spero tu possa capire di cosa stavo parlando...