MySQL查询列必须和group by字段一致吗?

数据库|group by查询出其他字段 数据库环境:MYSQL 5.7.19 解决group by只能查询特定字段而不能查询其他字段的问题。 新建一张表: CREATE TABLE LSQ_TEST_TABLE ( ID VARCHAR(64) NOT NULL COMMENT '主键', NAME VARCHAR(10) COMMENT '姓名', CLASS VARCHAR(10) C... 阅读详情

场景:查询各部门薪水最高的员工。

  • MySQL group by是如何决定哪一条数据留下的?
  • 那么target list和group by column不匹配就一定不能执行吗?

MySQL版本:8.0.27

场景:查询各部门薪水最高的员工。

CREATE TABLE `employee`  (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `dept` int NOT NULL COMMENT '部门',
  `user` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '员工',
  `salary` int NULL DEFAULT NULL COMMENT '薪水',
  `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
  `remark` varchar(512) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '备注',
  `modify_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '修改时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '员工' ROW_FORMAT = Dynamic;

INSERT INTO `employee` VALUES (1, 1, '张三', 1000, 0, NULL, '2021-12-23 09:20:19.606');
INSERT INTO `employee` VALUES (2, 1, '李四', 1500, 0, NULL, '2021-12-23 09:20:21.679');
INSERT INTO `employee` VALUES (3, 1, '王五', 2000, 0, NULL, '2021-12-23 09:20:23.371');
INSERT INTO `employee` VALUES (4, 2, '赵六', 1000, 0, NULL, '2021-12-23 09:21:59.373');
INSERT INTO `employee` VALUES (5, 2, '孙七', 1500, 0, NULL, '2021-12-23 09:22:15.000');

SELECT * FROM employee ;

MySQL查询列必须和group by字段一致吗?

方法一:

SELECT
	t1.* 
FROM
	employee t1
	LEFT JOIN employee t2 ON t2.dept = t1.dept AND t1.salary < t2.salary 
WHERE
	t2.salary IS NULL;

MySQL查询列必须和group by字段一致吗?

方法二:

SELECT
	* 
FROM
	( SELECT * FROM `employee` ORDER BY dept, salary DESC LIMIT 1000 ) t 
GROUP BY
	dept;

(不加limit可能会失效)

MySQL查询列必须和group by字段一致吗?

看起来结果是一样的,但第二种其实是会有问题的。

MySQL group by是如何决定哪一条数据留下的?

MySQL通过sql_mode来提供SQL语句的合法性检查,

在默认情况下,MySQL允许查询列target list中出现除了group by column、聚集函数等以外的表达式。

但是,那些不参与group by的字段具体会返回哪条数据的值在MySQL中是处于未定义规则的状态,

MySQL不承诺一定会返回哪条数据。

分组前的数据:

SELECT * FROM employee ORDER BY dept, salary DESC LIMIT 1000;

MySQL查询列必须和group by字段一致吗?

看起来方法二返回的是每个分组中的第一条的数据,

但实际上还会与存储引擎、物理位置、索引等有关,

如果是InnoDB的话,取决于在B+Tree上命中的第一条索引,

这里不展开说明,毕竟不是安全的用法,

有的时候可能返回的结果并不是我们想要的。

关于B+Tree,可以看下这篇文章:

通过B+Tree平衡多叉树理解InnoDB引擎的聚集和非聚集索引

所以对于target list中出现的不明确的列,MySQL是不确定哪一条数据留下的。

对于语法限制比较严格的数据库,都不支持target list中出现语义不明确的列,

MySQL中提供了一个修正的sql_mode,ONLY_FULL_GROUP_BY。

SET SESSION sql_mode = 'ONLY_FULL_GROUP_BY';

再执行方法二的SQL就被拒绝了:

SELECT
	* 
FROM
	( SELECT * FROM `employee` ORDER BY dept, salary DESC LIMIT 1000 ) t 
GROUP BY
	dept
> 1055 - Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 't.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
> 时间: 0s

'only_full_group_by'模式下MySQL会对target list和group by column中的基础列、表达式、别名列进行严格匹配。

那么target list和group by column不匹配就一定不能执行吗?

我们看下另外一条SQL:

# 订单
CREATE TABLE `order`  (
  `order_id` int NOT NULL AUTO_INCREMENT COMMENT '订单ID',
  `order_amount` int NULL DEFAULT NULL COMMENT '订单金额',
  PRIMARY KEY (`order_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '订单' ROW_FORMAT = DYNAMIC;

INSERT INTO `order` VALUES (1, 100);
INSERT INTO `order` VALUES (2, 103);
INSERT INTO `order` VALUES (3, 100);

# 订单明细
CREATE TABLE `order_detail`  (
  `order_detail_id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `order_id` int NOT NULL COMMENT '订单ID',
  `goods` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '商品名称',
  `goods_amount` int NOT NULL COMMENT '商品金额',
  PRIMARY KEY (`order_detail_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '订单明细' ROW_FORMAT = DYNAMIC;

INSERT INTO `order_detail` VALUES (1, 1, '苹果', 10);
INSERT INTO `order_detail` VALUES (2, 1, '橙子', 20);
INSERT INTO `order_detail` VALUES (3, 1, '香蕉', 70);
INSERT INTO `order_detail` VALUES (4, 2, '橘子', 50);
INSERT INTO `order_detail` VALUES (5, 2, '菠萝', 53);

查询订单中所有商品

SELECT
	t1.order_id,
	t1.order_amount,
	GROUP_CONCAT( t2.goods, t2.goods_amount ) 
FROM
	`order` t1
	LEFT JOIN order_detail t2 ON t2.order_id = t1.order_id 
GROUP BY
	t1.order_id;

MySQL查询列必须和group by字段一致吗?

这条SQL的target list和group by column并不是严格匹配的,但是也可以执行,

注意

t1.order_id是订单表的主键。

所以在'only_full_group_by'模式下,如果MySQL可以确定target list中所有列的返回值,

那么,即使target list和group by column中的基础列、表达式、别名列等不严格匹配,

MySQL也会认为它的语义是明确的,因此该条语句可以顺利通过。

原文
http://www.cnblogs.com/captaincat/p/15723369.html

Oracle group by与mysql group by的区别 在mysql中根据一个字段分组查询所有字段数据,group by之后的字段不用跟select之后的字段一致,即使没有加聚合函数也不会报错 在Oracle中对于group by的语法就比较严格,在oracle中规定,使用group by时,select后面所有不是聚合函数的字段,都必须出现在group by后面,如果错误使用函数会出现“ORA-00979 不是group by表达式”的错误 ... 阅读详情

相关推荐

优化MySQL查询中不必要的GROUP BY字段

通过仔细检查查询的目的、SELECT列表和HAVING子句,我们可以避免不必要的GROUP BY字段,并优化我们的查询。例如,假设我们有一个名为"orders"的表,其中包含订单信息,包括订单号(order_id)、客户ID(customer_id)和订单总额(total_amount)等字段。有时候,在编写复杂的查询语句时,我们可能会将不必要的字段包含在GROUP BY子句中,这样做会增加查询的复杂性和开销。通过将不必要的字段从GROUP BY子句中移除,我们可以提高查询的性能并确保结果的准确性。

QvisCs的博客 389

5.mysql group by(不同的字段) 查询出来的数据不一样剖析

desc tb_pushlog_20151201; id int(10) NO PRI auto_increment imei varchar(40) NO MUL imsi varchar(25) NO pushtime datetime NO 0000-00-00 00:00:00 ruleid int(11) YES MUL 0 channelid int(11) YES

liujian928730的专栏 1934

使用MySQL进行数据分组

在数据库中,数据分组是一种常见的操作,它允许我们根据特定的列或条件将数据分组成不同的集合,并对每个集合进行聚合计算。MySQL提供了强大的分组功能,使我们能够对数据进行灵活的分析和汇总。本文将介绍如何在MySQL中使用GROUP BY子句进行数据分组,并提供相应的源代码示例。我们可以使用GROUP BY子句对数据进行灵活的分组,并使用聚合函数进行各种计算。此外,我们还学习了如何对分组结果进行筛选和排序。除了基本的分组查询,我们还可以在GROUP BY子句中使用聚合函数来进行更复杂的计算。

BitCodeW的博客 205

MySQL查询列必须和group by字段一致吗?,linux内核技术手册中文版pdf

无论是哪家公司,都很重视高并发高可用的技术,重视基础,重视JVM。面试是一个双向选择的过程,不要抱着畏惧的心态去面试,不利于自己的发挥。同时看中的应该不止薪资,还要看你是不是真的喜欢这家公司,是不是能真的得到锻炼。其实我写了这么多,只是我自己的总结,并不一定适用于所有人,相信经过一些面试,大家都会有这些感触。最后我整理了一些面试真题资料,技术知识点剖析教程,还有和广大同仁一起交流学习共同进步,还有一些职业经验的分享。一个人可以走的很快,但一群人才能走的更远。

2401_84170522的博客 919

支付宝周期扣款实战:从签约到主动扣款的完整Java代码与避坑指南

本文详细介绍了支付宝周期扣款功能的完整Java实现流程,从协议签约到主动扣款的各个环节,包括业务模型设计、签约接口实现、异步通知处理、主动扣款技术等关键步骤。针对开发中常见的陷阱和问题,提供了实用的避坑指南和代码示例,帮助开发者高效实现连续支付功能,提升用户留存率。

weixin_27199085的博客 374

从Mule ESB到Apache Camel:手把手教你设计一个轻量级企业集成框架的‘心脏’

本文深入探讨了从Mule ESB到Apache Camel的轻量级企业集成框架设计实践,对比了两者在协议支持、消息处理能力和部署灵活性等方面的差异。通过实际代码示例和性能优化技巧,帮助开发者构建高效的核心模块,适用于现代微服务架构下的系统集成需求。

weixin_28738165的博客 374

高版本Mysql使用group by 分组报错

方法一:补全group by 后字段(不推荐这种方法,有时要查询的字段很多而且字段的内容不能保证不重复,如果全部补齐会造成查询数据丢失)。通过报错分析是由于group by 后的分组字段与查询字段不一致导致。打开navicat管理工具,按F6打开命令界面,依次输入以下语句。1)使用navicat管理工具连接mysql数据库。再重新执行就会发现不再报错。

Turn X7 1327

FastH3 + vLLM-Omni:MiniMax H3 视频生成本地部署与加速实战

随着多模态大模型在视频生成领域的普及,如何高效部署和加速推理成为工程实践的关键。vLLM作为高性能推理框架,通过PagedAttention和continuous batching显著优化了大模型吞吐;而FastH3则针对特定模型结构进行算子融合和CUDA优化。结合vLLM-Omni对多模态输入的支持,可以将MiniMax H3的视频生成耗时从分钟级压缩至秒级。本文以视频生成模型为例,详细拆解环境配置、推理优化与问题排查,为多模态模型本地部署提供参考。

ciya3282的博客 482

Mysql ONLY_FULL_GROUP_BY模式详解、group by非查询字段报错

一、问题报错 二、ONLY_FULL_GROUP_BY模式 2.1、什么是ONLY_FULL_GROUP_BY? 2.2、为什么要使用ONLY_FULL_GROUP_BY? 2.3、查看sql_mode 三、解决方法 3.1、关闭only_full_group_by模式 3.1.1、方法一:关闭当前会话中的only_full_group_by 3.1.2、方法二:永久关闭only_full_group_by模式 3.2、使用ANY_VALUE()函数 四、其他 4.1、无权限报错 4.2、select后面的

weixin_49114503的博客 1万+

【软件逆向学习记录】x64dbg调试器入门2:主调试窗口功能及字符串搜索功能介绍

在x64dbg中, ​​CPU视图 是调试过程中最核心的界面,通常被称为​​主调试窗口​​或​​调试视图​​,总体分为四个区域,代码区(反汇编),数据区(内存窗口),寄存器区和堆栈区,详细位置如下图:示例数据代码区最左侧为内存地址,第二块区域为程序代码值,原始程序代码经编译和汇编后变为二进制机器码存储在计算机中,调试器将其展示为易于阅读的十六进制,第三块区域是机器码反汇编后的汇编代码,最右侧为代码的注释窗口,有一些原始的注释,也可以自己添加注释PS:汇编和反汇编解释。

tusikong的博客 2922

直流有刷电机控制 - 认识电机(一)

电机控制学习

u011030644的博客 917

MySQL中的GROUP BY获取其他字段方法

详细版本见个人博客:MySQL中的GROUP BY获取其他字段方法 创建测试数据 CREATE TABLE语句用于创建表,在test数据库下面创建一张名为show_plan的表: create table show_plan( id int primary key auto_increment, name varchar(255), desp int, price int ); INSERT ...

dta0502的博客 1万+

[Dify实战] 招投标标书智能生成:模板套用 + 风险校验

摘要:本文提出基于Dify构建AI标书生成工作流,解决传统标书撰写中内容重复(80%复用率)、人工修改效率低、风险检查易出错等痛点。方案包含三大核心模块:1)智能生成(基于模板自动填充项目信息);2)风险校验(AI自动检查废标风险点);3)多角色协作。通过拆分标书结构、设置详细Prompt、建立风险检查清单,实现从"人工撰写"到"参数化自动生成+AI审核"的转型,最终输出标准格式文档并支持企业系统集成。典型应用场景下,系统能自动生成技术方案并识别关键风险(如支付安全合

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 827

MySQL分组查询group by实例

group by使用方法实例讲解 MySQL中GROUP BY语句用于对某个或某些字段查询分组,并返回这个字段重复记录的第一条,也就是每个小组(无排序)里面的第一条。 本文章通过实例向大家介绍mysql group by使用方法和需要注意的地方,感兴趣的朋友可以参考一下。 现在有这样一个数据表 book group by基本实例 我们对city字段进行分组查询 SELECT * FROM book GROUP BY city 结果如下: 可以看出,group by是根据city来进行分组的,因为book

杰少027 5596

基于Vivado MIG IP核的DDR3读写实验(top_rom_ddr/ddr_top)

一、前言 关于Vivado MIG IP核详细配置可以参考我之前的文章:基于Vivado MIG IP核的DDR3控制器(DDR3_CONTROL) 关于MIG IP核的用户端的接口时序可以参考这篇文章:XILINX 的 MIG IP(非AXI4)接口时序以及控制 二、实验内容 本次实验的内容主要是通过MIG IP核向DDR3读写数据,DDR3的接口时序由ddr_top模块提供: ddr_top模块的数据来源是wr_fifo,wr_fifo的数据实际来自top_sd_photo模块(本实验仿真

耐心的小黑的博客 3027

2026年经典爬虫案例专栏|第17篇:学术论文爬虫实战——知网与万方数据采集

字段名说明数据类型title论文标题字符串authors作者列表列表abstract摘要字符串keywords关键词列表列表journal发表期刊字符串year发表年份整数volume卷号字符串issue期号字符串pages页码范围字符串citations引用次数整数downloads下载次数整数doiDOI编号字符串url论文链接字符串学术论文爬虫是科研工作的重要辅助工具,可以帮助研究人员高效地收集和管理论文数据。

2201_76125261的博客 1062
上一篇: MySQL乐观锁扣减库存原理图解
下一篇: 延时消息常见实现方案
superjava_
博客等级 码龄5年 254粉丝 81原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值