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

MySQL中如何为数据分桶生成直方图(替代width_bucket)

MySQL实现width_bucket等宽分桶、生成直方图的方案

MySQL没有原生内置的width_bucket等宽分桶函数,可通过以下两种方案实现完全一致的分桶效果,满足直方图统计需求:

  • 通用算术计算方案(支持所有MySQL版本)
    直接通过边界判断+数学计算实现分桶逻辑,不需要额外创建对象,和PostgreSQL、Oracle的width_bucket返回规则完全对齐:值小于最小值返回0,大于等于最大值返回桶数+1,区间内按等宽区间返回1~N的桶号。
    对应示例SQL如下(和给出的PG/Oracle语法逻辑完全等价,将薪资在0~150000区间分为10个等宽桶):
    SELECT 
        department_id,
        last_name,
        salary,
        CASE
            WHEN salary < 0 THEN 0
            WHEN salary >= 150000 THEN 11
            ELSE FLOOR(salary / (150000/10)) + 1
        END AS salary_bucket
    FROM employees;
    
    上述逻辑里单个桶的宽度为15000,014999落在1号桶、1500029999落在2号桶,以此类推135000~149999落在10号桶。如果需要直接生成直方图统计结果,只需要按分桶字段做GROUP BY聚合计数即可。
  • 自定义函数方案(一劳永逸复用原生语法)
    如果需要频繁使用分桶逻辑,可以在MySQL中创建自定义的width_bucket函数,之后直接和PG、Oracle一样调用即可:
    DELIMITER //
    CREATE FUNCTION width_bucket(
        expr DECIMAL(20,4),
        min_val DECIMAL(20,4),
        max_val DECIMAL(20,4),
        bucket_count INT
    ) RETURNS INT
    DETERMINISTIC
    BEGIN
        DECLARE bucket_width DECIMAL(20,4);
        IF expr < min_val THEN
            RETURN 0;
        ELSEIF expr >= max_val THEN
            RETURN bucket_count + 1;
        END IF;
        SET bucket_width = (max_val - min_val) / bucket_count;
        RETURN FLOOR((expr - min_val)/bucket_width) + 1;
    END //
    DELIMITER ;
    
    函数创建完成后,原来在PG/Oracle中写的SQL不需要做任何修改,就可以直接在MySQL中执行:
    select department_id, 
           last_name, 
           salary, 
           width_bucket(salary,0,150000,10) 
    from employees;
    

注意:MySQL 8.0提供的NTILE()窗口函数是按记录行数均分的等频分桶,不是width_bucket对应的按数值区间均分的等宽分桶,二者逻辑差异很大,不要混用。

内容的提问来源于stack exchange,提问作者Anna Quoc Nguyen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 21:54:32