MySQL 分组函数全面详解与最佳实践

MySQL 分组函数全面详解与最佳实践

MySQL 分组函数(聚合函数)的核心知识、注意事项和高级应用技巧:


📊 分组函数核心列表

函数描述示例
COUNT()计算行数COUNT(*)
SUM()计算数值总和SUM(salary)
AVG()计算平均值AVG(score)
MAX()获取最大值MAX(price)
MIN()获取最小值MIN(price)
GROUP_CONCAT()连接分组字符串GROUP_CONCAT(name)
STDDEV()计算标准差STDDEV(price)
VAR_POP()计算总体方差VAR_POP(sales)

⚠️ 分组函数十大注意事项

1. NULL 值处理

SELECT COUNT(*),        -- 所有行数(包含NULL)COUNT(bonus),    -- 非NULL行数AVG(COALESCE(bonus, 0)) -- NULL转为0计算
FROM employees;

2. 分组字段选择

-- 错误:非分组字段出现在SELECT
SELECT department, name, AVG(salary) 
FROM employees; -- 报错或未定义行为-- 正确:所有非聚合字段必须出现在GROUP BY
SELECT department, name, AVG(salary)
FROM employees
GROUP BY department, name;

3. WHERE vs HAVING

-- WHERE:分组前过滤行
SELECT department, AVG(salary)
FROM employees
WHERE hire_date > '2020-01-01' -- 先过滤
GROUP BY department;-- HAVING:分组后过滤组
SELECT department, AVG(salary) avg_sal
FROM employees
GROUP BY department
HAVING avg_sal > 5000; -- 后过滤

4. 性能优化策略

-- 低效:全表扫描
SELECT department, AVG(salary)
FROM employees
GROUP BY department;-- 高效:添加索引
ALTER TABLE employees ADD INDEX idx_dept (department);

5. 隐式排序问题

-- 结果顺序不保证
SELECT department, COUNT(*)
FROM employees
GROUP BY department;-- 显式排序
SELECT department, COUNT(*) AS emp_count
FROM employees
GROUP BY department
ORDER BY emp_count DESC;

6. 分组函数嵌套限制

-- 允许:单层分组函数
SELECT AVG(MAX(salary)) -- ❌ 错误嵌套-- 正确:使用子查询
SELECT AVG(max_sal)
FROM (SELECT department, MAX(salary) AS max_salFROM employeesGROUP BY department
) dept_max;

7. DISTINCT 用法

-- 统计不重复值
SELECT COUNT(DISTINCT department), -- 不同部门数量COUNT(DISTINCT CASE WHEN salary > 5000 THEN 1 END) -- 高薪人数
FROM employees;

8. 空分组处理

-- 使用 COALESCE 处理空分组
SELECT COALESCE(department, '未分配') AS dept,COUNT(*) 
FROM employees
GROUP BY department;

9. 多列分组顺序

-- 分组顺序影响结果
SELECT YEAR(hire_date) AS hire_year,department,COUNT(*)
FROM employees
GROUP BY hire_year, department; -- 先按年再按部门

10. GROUP_CONCAT 限制

-- 默认截断长度1024字符
SET SESSION group_concat_max_len = 10000;SELECT department,GROUP_CONCAT(name ORDER BY salary DESC SEPARATOR '|') 
FROM employees
GROUP BY department;

🚀 高级分组技巧

1. 多级分组分析

SELECT YEAR(order_date) AS order_year,QUARTER(order_date) AS quarter,product_category,SUM(amount) AS total_sales,COUNT(DISTINCT customer_id) AS customers
FROM orders
GROUP BY order_year, quarter, product_category
WITH ROLLUP; -- 添加小计和总计行

2. 分组百分比计算

SELECT department,COUNT(*) AS emp_count,ROUND(COUNT(*) * 100.0 / SUM(COUNT(*)) OVER (), 2) AS pct
FROM employees
GROUP BY department;

3. 分组排名

SELECT department,name,salary,RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS dept_rank
FROM employees;

4. 分组比较分析

SELECT department,AVG(salary) AS avg_salary,AVG(salary) - (SELECT AVG(salary) FROM employees) AS diff_from_avg
FROM employees
GROUP BY department;

5. 时间序列分组

SELECT DATE_FORMAT(order_date, '%Y-%m') AS month,SUM(amount) AS monthly_sales,LAG(SUM(amount)) OVER (ORDER BY DATE_FORMAT(order_date, '%Y-%m')) AS prev_month
FROM orders
GROUP BY month;

🔧 性能优化指南

1. 索引策略

-- 复合索引优化分组
ALTER TABLE orders ADD INDEX idx_category_date (product_category, order_date);-- 覆盖索引
EXPLAIN SELECT product_category, COUNT(*) 
FROM orders 
GROUP BY product_category; -- 使用索引

2. 临时表优化

-- 增大临时表内存
SET tmp_table_size = 256*1024*1024; -- 256MB
SET max_heap_table_size = 256*1024*1024;-- 监控临时表使用
SHOW STATUS LIKE 'Created_tmp%';

3. 分区表优化

-- 按日期分区
CREATE TABLE sales (sale_id INT,sale_date DATE,amount DECIMAL(10,2)
) PARTITION BY RANGE (YEAR(sale_date)) (PARTITION p2020 VALUES LESS THAN (2021),PARTITION p2021 VALUES LESS THAN (2022),PARTITION p2022 VALUES LESS THAN (2023)
);-- 分区分组查询
SELECT YEAR(sale_date), SUM(amount)
FROM sales
GROUP BY YEAR(sale_date); -- 仅扫描相关分区

4. 物化视图(MySQL 8.0+)

-- 创建分组结果缓存
CREATE TABLE sales_summary AS
SELECT product_id, YEAR(order_date) AS year, SUM(amount) AS total
FROM orders
GROUP BY product_id, year;-- 定期刷新
REPLACE INTO sales_summary
SELECT product_id, YEAR(order_date), SUM(amount)
FROM orders
WHERE order_date > (SELECT MAX(order_date) FROM sales_summary)
GROUP BY product_id, YEAR(order_date);

💡 最佳实践总结

1. 分组设计原则

-- 明确分组粒度
SELECT DATE(order_date) AS day,  -- 按天HOUR(order_time) AS hour, -- 按小时COUNT(*) 
FROM orders
GROUP BY day, hour;

2. 安全处理大数据集

-- 分页处理大结果集
SELECT department, AVG(salary)
FROM employees
GROUP BY department
LIMIT 10 OFFSET 20; -- 第三页

3. 结果验证技巧

-- 验证分组总数
SELECT COUNT(DISTINCT department) 
FROM employees; -- 应与分组行数一致-- 交叉验证
SELECT (SELECT COUNT(*) FROM employees) AS total,SUM(emp_count) AS group_total
FROM (SELECT department, COUNT(*) AS emp_countFROM employeesGROUP BY department
) dept_groups;

4. 执行计划分析

-- 检查分组性能
EXPLAIN 
SELECT department, AVG(salary)
FROM employees
GROUP BY department;-- 关注以下指标:
-- 1. Using temporary (是否使用临时表)
-- 2. Using filesort (是否文件排序)
-- 3. key (使用的索引)

5. 避免常见陷阱

-- 陷阱1:错误处理NULL
SELECT department, AVG(bonus) -- 忽略NULL
FROM employees;-- 陷阱2:混淆WHERE和HAVING
SELECT department, AVG(salary)
FROM employees
WHERE AVG(salary) > 5000; -- 错误!WHERE不能使用聚合函数-- 陷阱3:未排序的分页
SELECT department, COUNT(*)
FROM employees
GROUP BY department
LIMIT 10; -- 结果随机

🚀 综合应用案例

销售分析报告

SELECT c.country,p.category,YEAR(o.order_date) AS order_year,COUNT(DISTINCT o.customer_id) AS customers,COUNT(*) AS orders,SUM(o.amount) AS revenue,AVG(o.amount) AS avg_order_value,GROUP_CONCAT(DISTINCT p.product_name ORDER BY p.product_name SEPARATOR ', ') AS products
FROM orders o
JOIN products p ON o.product_id = p.id
JOIN customers c ON o.customer_id = c.id
WHERE o.order_date BETWEEN '2023-01-01' AND '2023-12-31'
GROUP BY c.country, p.category, order_year WITH ROLLUP
HAVING revenue > 10000
ORDER BY country, category, order_year DESC;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/85195.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/85195.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

华为OD 最小循环子数组

1. 题意 给定一个由若干整数组成的数组 nums,请检查数组是否是由某个子数组重复循环拼接而成,请输出这个最小的子数组。 2. 题解 利用 k m p kmp kmp中的 n e x t next next数组性质,我们可以求出 n u m s nums nums中的最长公共 前缀后缀…

FreeCAD创作参数化凹形和水波纹式雨水箅子

这种非常流行的美观的雨水篦子是都市的宠爱,大家要多多去用。 用FC来创建参数化后,设计人员可以随意修改参数,满足自身的要求,调整各部件的位置,达到满意的布局,非常快捷。 水波纹雨水篦子 凹形雨水篦子

如何用一台服务器用dify私有部署通用的大模型应用?

dify是什么?如何用一台服务器用dify私有部署通用的大模型应用? Dify 是一款开源的大语言模型(LLM) 应用开发平台。它融合了后端即服务(Backend as Service)和LLMOps的理念,使开发者可以快速搭建生产级的生成式 AI 应用…

海洋捕食算法优化BP神经网络

引言BP神经网络因梯度下降法的固有缺陷,常出现训练震荡和早熟收敛。海洋捕食算法(MPA)受海洋生物觅食行为启发,其分阶段搜索策略(高速游动→自适应步长→局部开发)能有效平衡全局探索与局部开发。本文通过MPA优化BP初始权值及学习率,构建混合优化模型。 方法论2.1 MPA算…

C++/OpenCV 图像预处理与 PaddleOCR 结合进行高效字符识别

C/OpenCV 图像预处理与 PaddleOCR 结合进行高效字符识别 在许多实际应用场景中,直接从原始图片中提取文字的准确率可能不尽人意。图像中的噪声、光照不均、角度倾斜等问题都会严重干扰 OCR (Optical Character Recognition) 引擎的识别效果。本文将详细介绍如何利用…

线程的学习

1. 线程 1. 线程是一个进程内部的控制序列 2. 线程在进程内部运行,本质是在进程地址空间内运行 3. 进程:承担分配系统资源的基本实体 线程:CPU调度的基本单位 4. 线程在进程地址空间内运行 进程访问的大部分资源都是通过地址空间访问的 …

Qt Quick 与 QML(三)qml中的基础控件

一、基础控件 控件名称‌‌功能描述‌‌示例代码‌‌Rectangle‌基础绘图控件&#xff0c;创建矩形区域Rectangle {width: 100; height: 100<br> color: "red"; radius: 5}‌Text/Label‌文本显示控件Text {text: "Hello World";<br> font.pi…

Redis实现消息队列全解析:从基础到高级应用实战

目录 一、Redis作为消息队列的优势与局限 1.1 核心优势 1.2 适用场景 1.3 局限性及解决方案 二、Redis消息队列实现方案对比 三、List实现基础消息队列 3.1 生产者实现原理 3.2 消费者实现原理 3.3 可靠性增强&#xff1a;ACK机制 四、Pub/Sub实现发布订阅 4.1 消息发…

Windows应用商店中的国学启蒙教育应用

国学启蒙是中国传统文化教育的重要组成部分&#xff0c;主要以经典诵读、传统礼仪、历史故事等内容为载体&#xff0c;向儿童传递中华文化的核心价值观。帮助孩子建立文化认同感&#xff0c;培养良好的道德观念和行为习惯。通过学习古代圣贤的言行&#xff0c;儿童可以初步理解…

安科瑞UL认证ADL3000-E/C导轨表:工商业储能领域的智能之选

一、产品简介 ADL3000-E/C是安科瑞针对电力系统、工矿企业、公用设施的电力监控及能耗统计、管理需求而精心设计的一款智能仪表。该电能表具有精度高、体积小、安装方便等显著优点&#xff0c;为工商业储能系统的智能化管理提供了强有力的技术支持。 功能特性 测量与计量功能…

条件向量运算与三元表达式

在工程计算和数学建模中&#xff0c;我们经常需要根据条件动态选择不同的向量运算方式。这种需求在动力学系统、控制理论和计算机图形学中尤为常见。本文将探讨如何通过 Python 的三元表达式结合 SymPy 符号计算库&#xff0c;实现条件向量运算的高效解决方案。 我们从定义两…

文档开发组件Aspose旗下热门产品优势及应用场景介绍

✨Aspose 是什么&#xff1f; Aspose 是全球领先的文档处理组件厂商&#xff0c;主打一个字&#xff1a;全。 &#x1f4cc; 支持超 100 种文档/图像格式 &#x1f4cc; 覆盖 Word、Excel、PDF、PPT、OCR、BarCode、Email 等模块 &#x1f4cc; 支持 .NET、Java、Python、C、N…

龙虎榜——20250618

上证指数缩量长下影小阳线&#xff0c;个股下跌超3300只&#xff0c;总体护盘的板块表现相对更好。 深证指数缩量收小阳线&#xff0c;横盘震荡已有4天&#xff0c;等待方向选择。 2025年6月18日龙虎榜行业方向分析 1. 半导体 代表标的&#xff1a;沪电股份&#xff08;高阶P…

layui和vue父子级页面及操作

最近在老项目里面添加一些页面&#xff0c;项目太老只能在原有的项目基础和插件上添加代码 html //表格 <table id"dataTable"><thead><tr><th>序号</th><th>名称</th><th></th></tr></th…

Houdini 节点使用方法

Houdini 的节点系统是其程序化建模和特效制作的核心功能之一&#xff0c;通过节点网络实现程序化建模、特效制作、动力学模拟等复杂任务。掌握节点使用方法是高效创作的关键&#xff0c;以下是围绕用户需求的 全面、深入且结构化 的节点使用指南 一、节点基础操作 1. 创建与连…

license授权文件说明

license管理 1.使用场景 系统将自动检测license信息是否过期 - license过去前一个月&#xff0c;会显示warning&#xff1a;license file will expire in 30 days - 当license过去&#xff0c;会显示license file expired#注意 1. 数据库重启时才会启动 License 授权期限校验…

C++11中alignof和alignas的入门到精通指南

文章目录 一、引言二、内存对齐的概念和作用2.1 什么是内存对齐2.2 内存对齐的优势 三、alignof运算符3.1 定义和作用3.2 语法规则3.3 使用示例3.4 注意事项 四、alignas说明符4.1 定义和作用4.2 语法规则4.3 使用示例4.4 注意事项 五、alignof和alignas的结合使用六、实际应用…

防爆+高性能!ABB 防爆伺服电机HY系列守护安全生产

在石油、化工、火工等高风险行业中&#xff0c;如何在易燃易爆环境中确保设备安全稳定运行&#xff0c;同时兼顾高性能&#xff1f;ABB防爆伺服电机HY系列给出了完美答案&#xff01; 专为爆炸性环境设计&#xff0c;安全与性能兼得 ABB HY系列基于先进的HDS伺服平台打造&…

洪千武—华为海外HRBP

我的个人介绍 辰熙咨询创始人&CEO 2005年入职华为人力资源管理部 华为海外首批HRBP推动者、华为TUP股权激励实战顾问 华为IBM项目组成员、华为海外代表处AT成员 著有《OKR管理法则》、《力出一孔》 2005年以HR英文专才&#xff0c;从香港著名咨询公司被猎聘到华为人力…

测试:网络协议超级详解

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 </