sql >> Database >  >> RDS >> Mysql

MySQL Greatest N-resultaten met join-tabellen

ik denk dat ik het oplos :)

Eerst is hier een oplossing op basis van de manier waarop u bent begonnen. Maar er is een addertje onder het gras dat ik niet kon oplossen om exacte 3 (of welk nummer je ook kiest, ik kies er bijvoorbeeld 3) rij voor elke person_id te tonen. Het probleem is dat de oplossing is gebaseerd op het tellen van het aantal rijen met een rating_average groter dan de huidige rij. Dus als je 5 dezelfde topwaarde hebt, kun je ervoor kiezen om ze alle 5 te laten zien of helemaal niet en dat is niet goed. Dus hier is de manier waarop je dat doet ... (dit is natuurlijk een voorbeeld waarbij als je 4 topwaarden hebt, je ze allemaal laat zien (ik denk dat het helemaal geen zin heeft om de gegevens niet te tonen))...

 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

Belangrijk: Deze oplossing kan werken (om exact 3 rijen voor elke persoon weer te geven) als je geen waarde hebt die het zelf herhaalt... Hier is de Fiddle http://sqlfiddle.com/#!9/eb0fd/64 je kunt het probleem zien waarbij person_id 1 is!

Daarna heb ik wat meer gespeeld en het laten werken zoals je wilde in de vraag denk ik. Hier is een code voor:

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 is de viool voor die http://sqlfiddle.com/#!9/eb0fd/65 ...

GL!

P. S. sorry voor mijn Engels, ik hoop dat je zou kunnen begrijpen waar ik het over had...




  1. Door komma's gescheiden waarden van een kolom in rij splitsen, via Oracle SQL-query

  2. Hoe gebruik ik een subquery voor dbtable-optie in de jdbc-gegevensbron?

  3. Verzamel recursieve JSON-sleutels in Postgres

  4. FOUT 2002 (HY000):Kan geen verbinding maken met lokale MySQL-server via socket '/var/run/mysqld/mysqld.sock' (2)