You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何编写SQL查询获取各首字母开头的前3条有序结果?

实现按每个首字母取前3条记录的SQL查询

当然可以实现!这种按分组取Top N的需求在SQL里非常常见,下面分不同数据库场景给你对应的解决方案:

支持窗口函数的数据库(MySQL 8.0+、PostgreSQL、SQL Server等)

这类数据库支持ROW_NUMBER()窗口函数,写法简洁直观:

SELECT id, name
FROM (
    SELECT 
        id, 
        name,
        -- 按首字母分区,每个分区内按name排序生成行号
        ROW_NUMBER() OVER (PARTITION BY LEFT(name, 1) ORDER BY name) AS rn
    FROM your_table -- 替换成你的实际表名
) AS ranked_data
-- 筛选每个分区内的前3条
WHERE rn <= 3
-- 最终按首字母、行号排序,保证结果顺序符合预期
ORDER BY LEFT(name, 1), rn;

逻辑说明:

  • 子查询中用LEFT(name, 1)提取每条记录的首字母,通过PARTITION BY按首字母分组;
  • ORDER BY name确保每个分组内的记录按名称排序;
  • ROW_NUMBER()为每个分组内的记录生成唯一行号,外层查询筛选行号≤3的记录;
  • 最终排序保证结果按首字母顺序排列,每个首字母下的记录也按名称排序。

旧版MySQL(5.x及以下,不支持窗口函数)

如果你的MySQL版本较低,可以用用户变量来实现相同逻辑:

SELECT id, name
FROM (
    SELECT 
        id, 
        name,
        -- 当首字母和上一条相同时,行号+1,否则重置为1
        @row_num := IF(@current_letter = LEFT(name, 1), @row_num + 1, 1) AS rn,
        -- 更新当前记录的首字母到变量中
        @current_letter := LEFT(name, 1) AS current_letter
    FROM your_table,
         -- 初始化变量
         (SELECT @row_num := 0, @current_letter := '') AS init_vars
    -- 先按首字母、名称排序,保证变量计算的顺序正确
    ORDER BY LEFT(name, 1), name
) AS ranked_data
WHERE rn <= 3;

用你的示例数据测试的话,这个查询会返回:

id name
1 Abe
2 Andy
3 Asad
5 Berta
6 Bulma
7 Caan
8 Carl
9 Cesar
11 Dimitri

完全符合你期望的结果~

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

火山引擎 最新活动