[英]Get the max value in a specific group of rows
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, eg: 我想要实现的是获得每个国家/地区中最受欢迎的歌曲,例如:
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? 哪个mysql查询可以达到这个结果?
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
There is a trick that you can use with substring_index()
and group_concat()
: 您可以在
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;
EDIT: 编辑:
If you have big tables and lots of songs per country, I would suggest the not exists
approach: 如果您在每个国家/地区都设有大型餐桌和许多歌曲,那么我建议您使用
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
);
Along with an index on popular_song(country_id, rate)
. 以及对
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. 我建议使用
group_concat()
方法,因为OP已经有一个带有group by
的查询,因此技巧最容易插入到这样的查询中。
Here is another way I'v learned from @Gordon Linoff. 这是我从@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. 这是在MySql中实现
row_number()(Partition by ...)
窗口函数的方法。
You can do this with EXISTS like this: 您可以使用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)
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.
如果国家/地区的分级不是唯一的,则上述查询将为每个国家/地区返回几条记录。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.