Mysql
 sql >> Baza danych >  >> RDS >> Mysql

MySQL Greatest N Results with Join Tables

myślę, że to rozwiązałem :)

Najpierw jest jedno rozwiązanie oparte na sposobie, w jaki zacząłeś. Ale jest haczyk, którego nie mogłem rozwiązać, aby pokazać dokładnie 3 (lub dowolną liczbę, którą wybrałeś, na przykład wybrałem 3) dla każdego person_id. Problem polega na tym, że rozwiązanie polega na zliczeniu liczby wierszy o wartości rating_average większej niż bieżący wiersz. Więc jeśli masz 5 takich samych najwyższej wartości, możesz wybrać pokazanie wszystkich 5 lub nie pokazywać ich w ogóle, a to nie jest dobre. Oto sposób, w jaki to robisz... (oczywiście jest to przykład, w którym jeśli masz 4 najwyższe wartości, pokazujesz je wszystkie (myślę, że nie ma sensu nie pokazywać danych))...

 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

Ważne: To rozwiązanie może zadziałać (aby pokazać dokładnie 3 wiersze dla każdej osoby), jeśli nie masz wartości, która się powtarza... Oto Fiddle http://sqlfiddle.com/#!9/eb0fd/64 widać problem, gdzie person_id wynosi 1!

Potem grałem trochę więcej i sprawiłem, że działało tak, jak chciałeś w pytaniu, jak sądzę. Oto kod do tego:

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

Oto Fiddle dla tego http://sqlfiddle.com/#!9/eb0fd/65 ...

GL!

P. S. przepraszam za moją angielską nadzieję, że zrozumiesz, o czym mówię...




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Lista specyfikatorów formatu daty w MySQL

  2. Uzyskaj wiek osoby w MySQL

  3. node.js + łączenie połączeń mysql

  4. unikanie wstrzyknięć MySQL z klasą Zend_Db

  5. Odmowa polecenia aktualizacji dla użytkownika