You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从子查询选取前N条:world表按大洲取前5个国家的SQL实现

解决每个大洲按字母排序取前5个国家的问题

嗨,我懂你现在的困扰——用子查询加LIMIT 1确实能轻松拿到每个大洲的第一个国家,但要扩展到前5个的时候,这种单值匹配的方法就不管用了对吧?

最优解决方案:使用窗口函数ROW_NUMBER()

现代SQL数据库(比如PostgreSQL、MySQL 8.0+、SQL Server等)都支持窗口函数,这是处理这类“分组取Top N”问题的标准方案。我们可以给每个大洲内的国家按字母顺序分配行号,然后筛选出行号≤5的记录就行:

SELECT continent, country
FROM (
    SELECT 
        continent, 
        country,
        ROW_NUMBER() OVER (PARTITION BY continent ORDER BY country ASC) AS row_num
    FROM world
) ranked_countries
WHERE row_num <= 5
ORDER BY continent, row_num;

解释下这段代码的逻辑:

  • 内层子查询里,PARTITION BY continent会把数据按大洲分组,ORDER BY country ASC确保每个组内的国家按字母升序排列
  • ROW_NUMBER()函数给每个组内的每条记录分配一个唯一的行号,从1开始递增
  • 外层查询只保留行号≤5的记录,也就是每个大洲的前5个国家

兼容老版本数据库的替代方案

如果你的数据库不支持窗口函数(比如MySQL 5.x),可以用关联子查询来实现:

SELECT x.continent, x.country
FROM world x
WHERE (
    SELECT COUNT(*) 
    FROM world y 
    WHERE y.continent = x.continent 
      AND y.country <= x.country
) <= 5
ORDER BY x.continent, x.country;

这个方法的思路是:统计每个大洲内,字母顺序不晚于当前国家的数量,如果这个数量≤5,说明当前国家属于该大洲的前5个。不过要注意,这个方法在数据量大的时候效率会比窗口函数低很多,优先推荐窗口函数的方案。

内容的提问来源于stack exchange,提问作者Nick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:33:14