MySQL Greatest N Results with Join Tables

前端 未结 1 465
伪装坚强ぢ
伪装坚强ぢ 2021-01-15 21:20

Selecting the Top n Results, I\'ve seen the numerous posts and great articles on here about how to do it but I am struggling to do it with my data set. Most of the examples

相关标签:
1条回答
  • 2021-01-15 21:56

    i think i solve it :)

    First here is one solution based on the way you started. But there is a catch I couldn't solve it to show exact 3 (or whatever number you choose i pick 3 for example) row for each person_id. Problem is that solution is based on counting how many rows is there with the rating_average greater then current row. So if you have 5 same top value you could choose to show all 5 or not to show them at all and that's not good. So here is the way you do that... (of course this is example where if you have 4 top value you show them all (I think that no make sense at all to not show the data))...

     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
    

    Important: This solution can work (to show exact 3 rows for each person) if you don't have value that repeat it self... Here is the Fiddle http://sqlfiddle.com/#!9/eb0fd/64 you can see the problem where person_id is 1!

    After that i played a little more and make it work just as you wanted in the question i think. Here is a code for that:

    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
    

    Here is the Fiddle for that http://sqlfiddle.com/#!9/eb0fd/65 ...

    GL!

    P. S. sorry for my English hope you could understand what i was talking about...

    0 讨论(0)
提交回复
热议问题