2014-08-31 125 views
0

我有这两个表:获取最大价值

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 

我想达成什么是在每个国家得到最poular歌曲,例如:

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 

但是,这是行不通的。我尝试着查看“按组排序”等问题,但没有找到答案。

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

回答

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,所以最简单的方法就是插入这样的查询。

+0

Gordon,你在大桌子上试过这个吗? – Bulat 2014-09-01 08:53:03

+0

@Bulat。 。 。你可以看到我的编辑。 – 2014-09-01 12:45:08

+0

我猜如果每个组的记录数量不是很大,那么可以。 +1为有趣的答案。 – Bulat 2014-09-01 13:00:41

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

+0

为什么“和ps.rate = t1.rate”而不是“和ps.song_name = t1.song_name”? – Roy 2014-08-31 13:57:51

+0

@Roy,因为你需要最高等级的歌曲,所以加入歌曲名称没有任何意义 – 2014-08-31 14:00:53

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 ...)窗口函数的方式。

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) 

它不是在是否两首歌曲可以为每个国家,如果它们的等级相同返回的问题指定。如果评级在国家级别不唯一,上述查询将返回每个国家/地区的多个记录。