Get the max value in a specific group of rows

让人想犯罪 __ 提交于 2019-12-25 07:07:17

问题


I have these two tables:

popular_song

song_name  | rate | country_id
------------------------------
Tic Tac    | 10   | 1
Titanic    | 2    | 1
Love Boat  | 8    | 2
Battery    | 9    | 2

country

conutry_id | country
--------------------------
1          | United States
2          | Germany

What I'd like to achieve is to get the most poular song in each country, e.g.:

song_name | rate | country
--------------------------
Tic Tac   | 10   | United States
Battery   | 9    | Germany

I've tried this query:

SELECT MAX(rate), song_name, country
FROM popular_song ps JOIN country cnt
ON ps.country_id = cnt.country_id
GROUP BY country

But this doesn't work. I've tried looking at questions like "Order by before group by" but didn't find an answer.

Which mysql query could achieve this result?


回答1:


There is a trick that you can use with substring_index() and group_concat():

SELECT MAX(rate),
      substring_index(group_concat(song_name order by rate desc separator '|'), '|', 1) as song,
      country
FROM popular_song ps JOIN
     country cnt
     ON ps.country_id = cnt.country_id
GROUP BY country;

EDIT:

If you have big tables and lots of songs per country, I would suggest the not exists approach:

select rate, song country
from popular_song ps join
     country cnt
     on ps.country_id = cnt.country_id
where not exists (select 1
                  from popular_song ps2
                  where ps2.country_id = ps.country_id and ps2.rate > ps.rate
                 );

Along with an index on popular_song(country_id, rate). I recommended the group_concat() approach because the OP already had a query with a group by, so the trick is the easiest to plug into such a query.




回答2:


You can use another self join to popular songs table with the max rating

SELECT ps.*,cnt.country
FROM popular_song ps
JOIN (SELECT MAX(rate) rate, country_id FROM popular_song GROUP BY country_id) t1
ON(ps.country_id = t1.country_id and ps.rate= t1.rate)
 JOIN country cnt
ON ps.country_id = cnt.conutry_id

See Demo




回答3:


Here is another way I'v learned from @Gordon Linoff. Here is that question you could learn too.

SELECT  ps.*,cnt.country 
FROM 
  (SELECT popular_song.*,
         @rownum:= if (@c = country_id ,@rownum+1,if(@c := country_id, 1, 1) )as row_number
         FROM popular_song ,  
              (SELECT @c := '', @rownum:=0) r
         order by country_id, rate desc) as ps
LEFT JOIN country cnt
ON ps.country_id = cnt.conutry_id
WHERE ps.row_number = 1

This is the way of implementing row_number()(Partition by ...) window function in MySql.




回答4:


You can do this with EXISTS like this:

SELECT rate, song_name, cnt.country_id
FROM popular_song ps JOIN country cnt
ON ps.country_id = cnt.country_id
WHERE NOT EXISTS 
  (SELECT * FROM popular_song 
   WHERE ps.country_id = country_id AND rate > ps.rate)

It is not specified in the question whether two songs can be returned per country if their rating is the same. Above query will return several records per country if ratings are not unique at country level.



来源:https://stackoverflow.com/questions/25592552/get-the-max-value-in-a-specific-group-of-rows

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!