获取特定行组中的最大值

时间:2014-08-31 13:42:21

标签: mysql sql database greatest-n-per-group

我有这两个表:

popular_song

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

国家

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

我想要达到的目标是在每个国家获得最多的歌曲,例如:

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

我已尝试过此查询:

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

但这不起作用。我已经尝试过像#34;在分组前排序"但没有找到答案。

哪个mysql查询可以实现这个结果?

4 个答案:

答案 0 :(得分:3)

您可以使用另一个自我加入到最高评级

的流行歌曲表
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

答案 1 :(得分:2)

您可以使用substring_index()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;

编辑:

如果你有一个大表和每个国家的很多歌曲,我会建议采用not exists方法:

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
                 );

popular_song(country_id, rate)上的索引一起。我推荐使用group_concat()方法,因为OP已经有group by的查询,所以最简单的方法就是插入这样的查询。

答案 2 :(得分:1)

这是我从@Gordon Linoff那里学到的另一种方式。以下是that question您也可以学习。

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

这是在MySql中实现row_number()(Partition by ...)窗口函数的方法。

答案 3 :(得分:1)

您可以使用EXISTS执行此操作:

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)

如果评级相同,则每个国家/地区是否可以返回两首歌曲。如果评级在国家/地区级别不唯一,则上述查询将返回每个国家/地区的多条记录。