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

MySQL如何查询单表多个字段各自出现频次最高的众数值

MySQL 多字段众数查询方案

针对同时提取数据表多个字段众数的需求,以下提供两种可直接运行的实现方式,均满足「平局时任意返回一个频次最高值」的要求,基于示例表演示:

CREATE TABLE words(`letter1` char(1), `letter2` char(1));
    
INSERT INTO words(`letter1`, `letter2`)VALUES
    ('A', 'A'),    ('B', 'A'),    ('C', 'A'),    ('D', 'A'),    ('D', 'B'),
    ('B', 'B'),    ('D', 'B'),    ('A', 'C'),    ('B', 'D'),    ('D', 'A');

方案1:MySQL 8.0及以上版本(推荐,易扩展)

利用CTE做行转列,配合窗口函数分组排序取Top1,字段多的时候不需要重复写大量子查询:

WITH field_unpivot AS (
    -- 将所有需要统计的字段拆分为「字段名+字段值」的统一结构
    SELECT 'letter1' AS field_name, letter1 AS field_value FROM words
    UNION ALL
    SELECT 'letter2' AS field_name, letter2 AS field_value FROM words
),
freq_rank AS (
    -- 按字段分组,统计每个值的出现频次并按频次降序排名
    SELECT
        field_name,
        field_value,
        COUNT(*) AS appear_times,
        ROW_NUMBER() OVER (PARTITION BY field_name ORDER BY COUNT(*) DESC) AS rank_num
    FROM field_unpivot
    GROUP BY field_name, field_value
)
-- 取每个字段排名第1的值即为众数
SELECT field_name, field_value AS mode_value, appear_times
FROM freq_rank
WHERE rank_num = 1;

运行返回结果:

  • letter1的众数为D,共出现4次
  • letter2的众数为A,共出现5次

如果需要平局时返回所有频次并列最高的值,把ROW_NUMBER()替换为RANK()即可。

方案2:兼容MySQL 5.x 低版本

针对不支持窗口函数的老版本,可以直接用子查询+LIMIT 1分别取每个字段的众数,再合并结果,逻辑直观:

-- 长表格式返回结果
SELECT 'letter1' AS field_name, 
    (SELECT letter1 FROM words GROUP BY letter1 ORDER BY COUNT(*) DESC LIMIT 1) AS mode_value
UNION ALL
SELECT 'letter2' AS field_name, 
    (SELECT letter2 FROM words GROUP BY letter2 ORDER BY COUNT(*) DESC LIMIT 1) AS mode_value;

如果需要直接返回一行两列的宽表结果,不需要字段名列,可以简化为:

SELECT
    (SELECT letter1 FROM words GROUP BY letter1 ORDER BY COUNT(*) DESC LIMIT 1) AS letter1_mode,
    (SELECT letter2 FROM words GROUP BY letter2 ORDER BY COUNT(*) DESC LIMIT 1) AS letter2_mode;

两种写法都能正确返回对应字段的众数,字段新增时只需要按相同格式追加对应子查询即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 01:24:33