"这篇文档是关于MySQL中的分组查询,特别是如何进行不常见的查询操作,如按字段分组并选择特定记录,以及利用会话变量进行查询。文档中通过创建一个名为tb的测试表和插入数据来举例说明,表结构包含id、name、val和memo四个字段,并填充了相关的示例数据。特别提到了按name分组取val最大值所在行的方法。" 在MySQL中,分组查询是数据分析和报表生成的关键操作。它允许我们将数据根据一个或多个字段进行聚合,以便计算每个组的汇总值或者选择每个组的特定记录。在提供的描述中,我们看到了如何创建一个简单的表`tb`,并插入了9条记录,记录了不同name(a和b)对应的val(数值)和memo(备注)。 分组查询的基础语句是`GROUP BY`,例如要按`name`字段分组并查看每个组的平均`val`,可以使用以下SQL: ```sql SELECT name, AVG(val) as avg_val FROM tb GROUP BY name; ``` 这个查询将返回每个name组的平均val值。 文档中提到的“无条件取前N条”或“后N条”记录,这通常涉及到`LIMIT`和`OFFSET`子句。比如,如果我们想获取每个name组中val最高的前两条记录,可以使用以下复杂查询: ```sql SELECT t1.* FROM ( SELECT name, val, ROW_NUMBER() OVER(PARTITION BY name ORDER BY val DESC) as row_num FROM tb ) t1 WHERE t1.row_num <= 2; ``` 这里使用窗口函数`ROW_NUMBER()`对每个name组内的记录进行排序,并分配行号,然后只选取行号小于等于2的记录。 会话变量在查询中的应用可以提高灵活性,特别是在处理复杂逻辑时。例如,我们可以设置一个会话变量来保存每组的最大val,然后用它来筛选记录: ```sql SET @max_val = NULL; SELECT * FROM ( SELECT name, val, IF(@max_val IS NULL OR val > @max_val, @max_val := val, @max_val) as max_in_group, @row_num := IF(@max_val = val, @row_num, @row_num + 1) as row_num FROM tb, (SELECT @max_val := NULL, @row_num := 0) r GROUP BY name, val ORDER BY name, val DESC ) t WHERE t.row_num = 1; ``` 这个查询首先找到每个name组的max_val,然后用`IF`和`@row_num`来跟踪每组中最大val出现的次数,最终选取每个组中val最大的那条记录。 以上就是关于MySQL分组查询和会话变量使用的一些核心知识点,它们在实际的数据分析和处理中有着广泛的应用。通过熟练掌握这些技巧,可以更有效地从数据库中提取所需信息。
CREATE TABLE `tb` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(10) CHARACTER SET latin1 DEFAULT NULL,
`val` int(11) DEFAULT NULL,
`memo` varchar(20) CHARACTER SET latin1 DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8
INSERT INTO `test_db`.`tb` (`id`, `name`, `val`, `memo`) VALUES ('1', 'a', '8', 'sfsfds');
INSERT INTO `test_db`.`tb` (`id`, `name`, `val`, `memo`) VALUES ('2', 'a', '9', 'sfdsf');
INSERT INTO `test_db`.`tb` (`id`, `name`, `val`, `memo`) VALUES ('3', 'a', '7', 'fdsggsdf');
INSERT INTO `test_db`.`tb` (`id`, `name`, `val`, `memo`) VALUES ('4', 'b', '3', 'sdfdsggsf');
INSERT INTO `test_db`.`tb` (`id`, `name`, `val`, `memo`) VALUES ('5', 'b', '2', 'sdfdfte');
INSERT INTO `test_db`.`tb` (`id`, `name`, `val`, `memo`) VALUES ('6', 'b', '2', 'sdfdfte');
INSERT INTO `test_db`.`tb` (`id`, `name`, `val`, `memo`) VALUES ('7', 'b', '6', 'sgsdfdsfds');
INSERT INTO `test_db`.`tb` (`id`, `name`, `val`, `memo`) VALUES ('8', 'b', '5', 'sfsdg');
INSERT INTO `test_db`.`tb` (`id`, `name`, `val`, `memo`) VALUES ('9', 'b', '4', 'sfdsgdg');
按name分组取val最大的值所在行的数据
//mysql直接group by就行了
select id ,name,memo,max(val) as val from tb group by name;
/**花式按name分组取val最大的值所在行的数据实际并无必要
select a.* from tb a where val = (select max(val) from tb where name = a.name) order by a.name
select a.* from tb a where not exists(select 1 from tb where name = a.name and val > a.val)
下载后可阅读完整内容,剩余2页未读,立即下载
- 粉丝: 3
- 资源: 5
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- C++多态实现机制详解:虚函数与早期绑定
- Java多线程与异常处理详解
- 校园导游系统:无向图实现最短路径探索
- SQL2005彻底删除指南:避免重装失败
- GTD时间管理法:提升效率与组织生活的关键
- Python进制转换全攻略:从10进制到16进制
- 商丘物流业区位优势探究:发展战略与机遇
- C语言实训:简单计算器程序设计
- Oracle SQL命令大全:用户管理、权限操作与查询
- Struts2配置详解与示例
- C#编程规范与最佳实践
- C语言面试常见问题解析
- 超声波测距技术详解:电路与程序设计
- 反激开关电源设计:UC3844与TL431优化稳压
- Cisco路由器配置全攻略
- SQLServer 2005 CTE递归教程:创建员工层级结构