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

MySQL按关联名称数量排序:解决GROUP BY丢失关联名称问题

嘿,这个问题我太熟了!你想要的是保留所有和Id关联的名称,同时按每个Id对应的名称总数从多到少排序,直接GROUP BY Id确实会把同一Id下的名称合并掉,咱们换两个思路就能搞定👇

方法1:用窗口函数(推荐,适用于MySQL 8.0+、PostgreSQL、SQL Server等现代数据库)

窗口函数可以在不聚合原始行的前提下,给每一行算出它所属Id的名称总数,完美解决“保留所有行+按总数排序”的需求:

SELECT 
    Id, 
    Name, 
    -- 按Id分组,统计每个组的Name数量(如果要包含NULL的Name用COUNT(*))
    COUNT(Name) OVER (PARTITION BY Id) AS name_count
FROM 
    your_table_name
-- 先按总数降序,再按Id排序(同数量的Id可以稳定排序)
ORDER BY 
    name_count DESC, Id;

简单解释下:

  • PARTITION BY Id会把数据按Id拆分成分组,COUNT(Name)统计每个组里的非NULL名称数量
  • 这样每一行都会保留原始的Id和Name,同时带上该Id对应的名称总数
  • 最后按name_count降序排列,就能让名称数量最多的Id对应的所有行排在最前面
方法2:子查询+JOIN(兼容旧版数据库,比如MySQL 5.x)

如果你的数据库不支持窗口函数,那就先单独算出每个Id的名称总数,再把这个结果和原表关联,同样能保留所有原始行:

SELECT 
    t.Id, 
    t.Name, 
    cnt.name_count
FROM 
    your_table_name t
-- 关联子查询算出的每个Id的名称总数
JOIN (
    SELECT 
        Id, 
        COUNT(Name) AS name_count
    FROM 
        your_table_name
    GROUP BY 
        Id
) cnt ON t.Id = cnt.Id
-- 按总数降序排序
ORDER BY 
    cnt.name_count DESC, t.Id;

额外注意事项:

  • 如果你的Name字段可能存在NULL值,记得把COUNT(Name)改成COUNT(*),因为COUNT(Name)会自动忽略NULL,而COUNT(*)会统计该Id下的所有行数(包括Name为NULL的行),根据你的实际业务需求选择
  • 如果想要同数量的Id下,再按名称排序,可以把ORDER BY改成name_count DESC, Id, Name

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:36:05