Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MySQL Greatest N-Ergebnisse mit Join-Tabellen

Ich glaube, ich löse es :)

Hier ist zunächst eine Lösung, die auf der Art und Weise basiert, wie Sie angefangen haben. Aber es gibt einen Haken, den ich nicht lösen konnte, um genau 3 (oder welche Zahl Sie auch wählen, ich wähle zum Beispiel 3) Zeilen für jede person_id anzuzeigen. Das Problem ist, dass die Lösung darauf basiert, zu zählen, wie viele Zeilen vorhanden sind, wobei der Bewertungsdurchschnitt größer als die aktuelle Zeile ist. Wenn Sie also 5 gleiche Top-Werte haben, können Sie wählen, ob Sie alle 5 anzeigen oder sie überhaupt nicht anzeigen möchten, und das ist nicht gut. So machen Sie das also ... (natürlich ist dies ein Beispiel, bei dem Sie, wenn Sie 4 Top-Werte haben, sie alle anzeigen (ich denke, dass es überhaupt keinen Sinn macht, die Daten nicht anzuzeigen)) ...

 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

Wichtig: Diese Lösung kann funktionieren (um genau 3 Zeilen für jede Person anzuzeigen), wenn Sie keinen Wert haben, der sich selbst wiederholt ... Hier ist die Fiddle http://sqlfiddle.com/#!9/eb0fd/64 Sie können das Problem sehen, wo person_id 1 ist!

Danach habe ich ein bisschen mehr gespielt und es funktioniert so, wie Sie es in der Frage wollten, denke ich. Hier ist ein Code dafür:

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

Hier ist die Fiddle dafür http://sqlfiddle.com/#!9/eb0fd/65 ...

GL!

P. S. Entschuldigung für mein Englisch, hoffe du konntest verstehen, wovon ich rede...