解决Mysql分组查询语句Expression #1 of SELECT list is not in GROUP BY clause ... ... 替换方案

前言

mysql的分组查询算是日常开发中用的最频繁的语句之一。

问题发现

公司有个需求,需要用到分组查询,本以为很简单的sql语句,硬生生的弄了几个小时,特此记录下来。

以某数据库查询为例,sql语句如下:

SELECT * FROM `customer` GROUP BY customer.sex

返回错误信息

SELECT * FROM `customer` GROUP BY customer.sex
> 1055 - Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 
'member.customer.member_no' which is not functionally dependent on columns in GROUP BY clause; 
 this is incompatible with sql_mode=only_full_group_by
> 时间: 0.078s

似乎只能这样做:

SELECT sex FROM `customer` GROUP BY customer.sex

在这里插入图片描述这种查询只能查对应一个字段,显然不满足产品需求。这是因为使用GROUP BY 语句违背了sql_mode=only_full_group_by。因为mysql版本5.7之后默认的模式是ONLY_FULL_GROUP_BY。

如果启用了ONLY_FULL_GROUP_BY SQL模式(默认情况下),MySQL将拒绝选择列表,HAVING条件或ORDER BY列表的查询引用在GROUP BY子句中既未命名的非集合列,也不在功能上依赖于它们。

看了网上很多办法,有修改全局配置的,或者换mysql版本的,这些方案似乎可以解决部分问题,但是如果项目已经生产使用了,如果再来操作这些,改动有点太大了,既然都行不通,那就用sql语句的方式让他行得通。

问题解决

假设:现有需求查询会员最新的登陆记录。

表结构如下:

用户表

CREATE TABLE `user` (
  `id` int NOT NULL AUTO_INCREMENT,
  `auth` varchar(255) DEFAULT NULL COMMENT '最高权限用户=admin',
  `name` varchar(11) NOT NULL COMMENT '用户名',
  `pwd` varchar(255) DEFAULT NULL COMMENT '密码',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `status` int NOT NULL COMMENT '0为不启用,1为启用',
  `role_id` int DEFAULT NULL COMMENT '用户对应角色,对应role表id',
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`name`) COMMENT '登录名'
) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

表数据
在这里插入图片描述

操作日志表

CREATE TABLE `log_login` (
  `id` int NOT NULL AUTO_INCREMENT,
  `user_id` int DEFAULT NULL,
  `user_name` varchar(255) DEFAULT NULL,
  `operate_name` varchar(255) DEFAULT NULL,
  `ctime` datetime DEFAULT NULL,
  `utime` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;

表数据
在这里插入图片描述

方案一:再有主键的情况下,通过max()函数获取最新的id进行查询

在有主键的情况下:

  • 先通过分组user_id。
  • 再使用max()函数获取每个用户的主键id,一般情况下主键id应该都是递增的形式。
  • 再把查询的每个用户的主键id,当做查询条件带入到第二条sql语句中,这样一来就可以获取到完整的一条数据,也可以和其他表关联查询。

示例代码如下:

SELECT
	log_login.*,
	user.*
FROM
	log_login
	INNER JOIN `USER` ON log_login.user_id = `user`.id 
WHERE
	log_login.id IN ( SELECT max( id ) AS id FROM log_login GROUP BY user_id )

查询结果如图:
在这里插入图片描述

方案二:没有主键的情况下,通过ctime倒排取第一条数据进行查询

没有主键的情况下,最少也要满足两个条件:

  1. 有可以倒排的字段(比如:ctime创建时间)。
  2. 有唯一字段。

假设现在这个表结构没有主键了,id当作唯一字段。

  • 先通过ctime倒排,当做第二条sql语句的子查询,子查询只能查询一行数据,所以加个limit限制一条,然后查询条件将子查询的user_id与第二条sql语句的user_id匹配,这样每个user_id对应最新时间的唯一id(注:多个相同user_id会有多条数据,但都是最新唯一id),
  • 然后把第二个查询语句,通过user_id进行分组,得到每个用户最新时间段内的唯一id(去除重复user_id的多条数据),再把每个用户的唯一id当做查询条件带入到第三条sql语句中,这样一来就可以获取到完整的一条数据,也可以和其他表关联查询,示例代码如下:
SELECT
	log_login.*,
	USER.* 
FROM
	log_login
	INNER JOIN `USER` ON log_login.user_id = `user`.id 
WHERE
	log_login.id IN (
	SELECT
		( SELECT id FROM log_login WHERE log_login.user_id = log.user_id ORDER BY ctime DESC LIMIT 0, 1 ) AS id 
	FROM
		log_login log 
	GROUP BY
	log.user_id 
	)

查询结果如图:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用:1055 - Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'senior_two.score.student_id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by 。 引用:这个错误是由于 MySQL 的新版本中默认开启了ONLY_FULL_GROUP_BY模式,即在 GROUP BY 语句中的 SELECT 列表中,只能包含分组或聚合函数,不能包含其他列。而你的查询语句中出现了一个列senior_two.score.student_id,它既没有被分组也没有被聚合,因此 MySQL 报出了这个错误。 。 引用:如果启用了only_full_group_by SQL模式(在默认情况下是这样),那么MySQL就会拒绝选择列表、条件或顺序列表引用的查询,这些查询将引用组中未命名的非聚合列,而不是在功能上依赖于它们。(在5.7.5之前,MySQL没有检测...。 根据引用,这个错误意味着在SELECT语句中的第二个表达式不在GROUP BY子句中,并且包含了一个非聚合的列'senior_two.score.student_id'。这与sql_mode=only_full_group_by模式不兼容。 根据引用,这个错误是由于MySQL的新版本中默认开启了ONLY_FULL_GROUP_BY模式。在GROUP BY语句SELECT列表中,只能包含分组或聚合函数,不能包含其他列。而你的查询语句中出现了一个列'senior_two.score.student_id',它既没有被分组也没有被聚合,因此MySQL报出了这个错误。 如果你启用了only_full_group_by SQL模式(默认情况下是启用的),那么MySQL会拒绝选择列表、条件或顺序列表引用的查询,这些查询将引用组中未命名的非聚合列,而不是在功能上依赖于它们。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [1055 - Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column ‘se](https://blog.csdn.net/m0_61615803/article/details/130076452)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [解决大于5.7版本mysql的分组报错Expression #1 of SELECT list is not in GROUP BY clause and contains ...](https://download.csdn.net/download/weixin_38743076/13698627)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值