关于 group_concat() 的问题

VitoYi 2019-03-11 11:52:50
我在使用 group_concat() 的时候遇到了问题,我的需求是,有一部电影,该电影关联了两个分类,那么左关联查询的时候,会出现两条记录。
我使用 group_concat() 想让两行分类数据合并成一行数据。

# 一、首先上测试的表结构和数据的 sql 吧



Navicat Premium Data Transfer

Source Server : 本机
Source Server Type : MySQL
Source Server Version : 80012
Source Host : localhost:3306
Source Schema : test

Target Server Type : MySQL
Target Server Version : 80012
File Encoding : 65001

Date: 11/03/2019 23:26:12
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for actor
-- ----------------------------
DROP TABLE IF EXISTS `actor`;
CREATE TABLE `actor` (
`actor_id` int(11) NOT NULL AUTO_INCREMENT,
`actor_name` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '演员名称',
PRIMARY KEY (`actor_id`)
) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=utf8 COMMENT='演员表';

-- ----------------------------
-- Records of actor
-- ----------------------------
BEGIN;
INSERT INTO `actor` VALUES (4, '古月方源');
INSERT INTO `actor` VALUES (5, '凤九歌');
INSERT INTO `actor` VALUES (6, '吴帅');
INSERT INTO `actor` VALUES (8, '龙公');
INSERT INTO `actor` VALUES (9, '星宿仙尊');
COMMIT;

-- ----------------------------
-- Table structure for genre
-- ----------------------------
DROP TABLE IF EXISTS `genre`;
CREATE TABLE `genre` (
`genre_id` int(11) NOT NULL AUTO_INCREMENT,
`genre_name` varchar(255) COLLATE utf8mb4_bin NOT NULL,
PRIMARY KEY (`genre_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

-- ----------------------------
-- Records of genre
-- ----------------------------
BEGIN;
INSERT INTO `genre` VALUES (1, '科幻');
INSERT INTO `genre` VALUES (2, '剧情');
INSERT INTO `genre` VALUES (3, '喜剧');
INSERT INTO `genre` VALUES (4, '恐怖');
COMMIT;

-- ----------------------------
-- Table structure for movie
-- ----------------------------
DROP TABLE IF EXISTS `movie`;
CREATE TABLE `movie` (
`movie_id` int(11) NOT NULL AUTO_INCREMENT,
`movie_name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
PRIMARY KEY (`movie_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=156 DEFAULT CHARSET=utf8 COMMENT='电影表';

-- ----------------------------
-- Records of movie
-- ----------------------------
BEGIN;
INSERT INTO `movie` VALUES (1, '蛊真人');
INSERT INTO `movie` VALUES (2, '教父');
INSERT INTO `movie` VALUES (3, '七武士');
INSERT INTO `movie` VALUES (4, '天堂电影院');
COMMIT;

-- ----------------------------
-- Table structure for movie_actor
-- ----------------------------
DROP TABLE IF EXISTS `movie_actor`;
CREATE TABLE `movie_actor` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`movie_id` int(11) NOT NULL DEFAULT '0' COMMENT '电影id',
`actor_id` int(11) NOT NULL COMMENT '演员id',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8 COMMENT='电影、演员中间表';

-- ----------------------------
-- Records of movie_actor
-- ----------------------------
BEGIN;
INSERT INTO `movie_actor` VALUES (1, 1, 4);
INSERT INTO `movie_actor` VALUES (2, 1, 5);
INSERT INTO `movie_actor` VALUES (3, 1, 5);
INSERT INTO `movie_actor` VALUES (4, 1, 8);
INSERT INTO `movie_actor` VALUES (5, 1, 9);
INSERT INTO `movie_actor` VALUES (6, 2, 3);
INSERT INTO `movie_actor` VALUES (7, 3, 5);
INSERT INTO `movie_actor` VALUES (8, 2, 9);
INSERT INTO `movie_actor` VALUES (9, 3, 8);
INSERT INTO `movie_actor` VALUES (10, 3, 9);
INSERT INTO `movie_actor` VALUES (11, 4, 8);
INSERT INTO `movie_actor` VALUES (12, 5, 4);
COMMIT;

-- ----------------------------
-- Table structure for movie_genre
-- ----------------------------
DROP TABLE IF EXISTS `movie_genre`;
CREATE TABLE `movie_genre` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`movie_id` int(11) NOT NULL DEFAULT '0' COMMENT '电影id',
`genre_id` int(11) NOT NULL DEFAULT '0' COMMENT '分类id',
PRIMARY KEY (`id`),
KEY `asset_id` (`movie_id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COMMENT='电影、分类中间表';

-- ----------------------------
-- Records of movie_genre
-- ----------------------------
BEGIN;
INSERT INTO `movie_genre` VALUES (1, 1, 2);
INSERT INTO `movie_genre` VALUES (2, 1, 4);
INSERT INTO `movie_genre` VALUES (3, 2, 2);
INSERT INTO `movie_genre` VALUES (4, 3, 2);
INSERT INTO `movie_genre` VALUES (5, 3, 4);
INSERT INTO `movie_genre` VALUES (6, 3, 3);
INSERT INTO `movie_genre` VALUES (7, 4, 2);
INSERT INTO `movie_genre` VALUES (8, 4, 3);
COMMIT;

SET FOREIGN_KEY_CHECKS = 1;



# 二、重现一下我的操作

## 1、查询电影和分类




## 2、将分类合并成一行



这一步应该也没什么问题。

## 3、再加入一列



这里就出问题了。

求大神帮忙解答一下。


# 三、还有一个问题


还有一个问题就是,如上面的 sql, 在新版的 MySQL 中可能会出现如下错误:

引用
Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'xxx.


同样的 sql, 在公司没问题,但是在我个人电脑上就会报错,我的 MySQL 版本是 8.0.12, 网上查了一下,说是:

引用
MySQL 5.7.5和up实现了对功能依赖的检测。如果启用了only_full_group_by SQL模式(在默认情况下是这样),那么MySQL就会拒绝选择列表、条件或顺序列表引用的查询,这些查询将引用组中未命名的非聚合列,而不是在功能上依赖于它们。


是因为我的 SQL 写的有问题吗?
...全文
628 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
过眼浮云866 2019-06-20
  • 打赏
  • 举报
回复
“MySQL 5.7.5和up实现了对功能依赖的检测。如果启用了only_full_group_by SQL模式(在默认情况下是这样),那么MySQL就会拒绝选择列表、条件或顺序列表引用的查询,这些查询将引用组中未命名的非聚合列,而不是在功能上依赖于它们。”


这个是mysql的配置文件的一个参数(sql_mode)控制的,在mysql 5.7以上的版本做过修改,默认是(ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
),如果出现group by, 则分组的字段必须出现在查询的显示字段里面(也就是select 的后面的字段),需要把 sql_mode参数重新赋值;
操作如下:
1,查看sql_mode
select @@sql_mode
查询出来的结果如下:ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
2,去掉ONLY_FULL_GROUP_BY,重新设置值
set @@sql_mode ='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER
,NO_ENGINE_SUBSTITUTION';
3,第二步是改变了全局sql_mode,对于新建的数据库有效。对于已存在的数据库,则需要在对应的数据下执行:
set sql_mode ='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';

执行完成之后,重启数据库即可;


VitoYi 2019-03-28
  • 打赏
  • 举报
回复
人工置顶,求助大神
VitoYi 2019-03-12
  • 打赏
  • 举报
回复
引用 1 楼 leo_lesley 的回复:
你这中连接肯定会出现这个问题的,两个结果集的记录数不一样,他会已最多的来匹配,所以出现上面的结果, 你需要用两个查询分别 group_concat() , 然后按movie_id来合并
谢谢,能否说的详细一点?我比较菜
leo_lesley 2019-03-12
  • 打赏
  • 举报
回复
你这中连接肯定会出现这个问题的,两个结果集的记录数不一样,他会已最多的来匹配,所以出现上面的结果, 你需要用两个查询分别 group_concat() , 然后按movie_id来合并
leo_lesley 2019-03-12
  • 打赏
  • 举报
回复


-- 你试试这个语句
select *
from (
select
m.movid_id ,
m.movid_name ,
group_concat(g.genre_name) genre_name
FROM
movie m
left join movie_genre mg on mg.movie_id = m.movie_id
left join genre g on g.genre_id = mg.genre_id
group by m.movie_id
) a join
(
select
m.movid_id ,
m.movid_name ,
group_concat(g.actor_name) actor_name
FROM
movie m
left join movie_actor ma on mg.movie_id = m.movie_id
left join actor a on g.actor_id = mg.actor_id
group by m.movie_id
) b on a.movid_id = b.movid_id


代码下载地址: https://pan.quark.cn/s/bc087ffa872a "测控电路课后习题详解"文件.pdf是一份极具价值的学术资料,其中系统地阐述了测控电路的基础理论、系统构造、核心特性及其实际应用领域。 以下是对该文献的深入解读和系统梳理:1.1测控电路在测控系统中的核心功能测控电路在测控系统的整体架构中扮演着不可或缺的角色。 它承担着对传感器输出信号进行放大、滤除杂音、提取有效信息等关键任务,并且依据测量与控制的需求,执行必要的计算、处理与变换操作,最终输出能够驱动执行机构运作的指令信号。 测控电路作为测控系统中最具可塑性的部分,具备易于放大信号、转换模式、传输数据以及适应多样化应用场景的优势。 1.2决定测控电路精确度的关键要素影响测控电路精确度的核心要素包括:(1)噪声与干扰的存在;(2)失调现象与漂移效应,尤其是温度引起的漂移;(3)线性表现与保真度水平;(4)输入输出阻抗的特性影响。 在这些要素中,噪声干扰与失调漂移(含温度效应)是最为关键的因素,需要给予高度关注。 1.3测控电路的适应性表现测控电路在测控系统中展现出高度的适应性,具体表现在:* 具备选择特定信号、灵活实施各类转换以及进行信号处理与运算的能力* 实现模数转换与数模转换功能* 在直流与交流、电压与电流信号之间进行灵活转换* 在幅值、相位、频率与脉宽信号等不同参数间进行转换* 实现量程调整功能* 对信号实施多样化的处理与运算,如计算平均值、差值、峰值、绝对值,进行求导数、积分运算等,以及实现非线性环节的线性化处理、逻辑判断等操作1.4测量电路输入信号类型对电路结构设计的影响测量电路的输入信号类型对其电路结构设计产生显著影响。 依据传感器的类型差异,输入信号的形态也呈现多样性。 主要可分为...
高效的多分辨率融合技术对具有标签不确定性的遥感数据进行处理(Matlab代码实现)内容概要:本文介绍了基于Matlab代码实现的高效多分辨率融合技术,用于处理具有标签不确定性的遥感数据。该方法通过融合不同分辨率的遥感图像,提升数据的空间与光谱信息一致性,有效应对遥感数据中标注不准确或模糊的问题,从而提高后续分类、检测或识别任务的精度与鲁棒性。文中详细阐述了算法的核心流程,包括多尺度数据配准、特征提取、不确定性建模及融合策略优化,并提供了完整的Matlab实现代码,便于科研人员复现实验并进行二次开发。; 适合人群:具备一定遥感图像处理基础和Matlab编程能力的研究生、科研人员及从事地理信息系统、环境监测、城市规划等相关领域的技术人员。; 使用场景及目标:①应用于土地利用分类、环境变化监测、灾害评估等存在标注误差的实际遥感项目中;②旨在提升遥感数据分析的准确性与可靠性,特别是在训练样本有限或标签质量较低的情况下;③为相关领域提供可复现的技术方案与代码参考。; 阅读建议:建议读者结合提供的Matlab代码逐段理解算法实现细节,重点关注多分辨率配准与不确定性融合模块的设计逻辑,同时可尝试在自有数据集上进行迁移实验以加深理解。

57,064

社区成员

发帖
与我相关
我的任务
社区描述
MySQL相关内容讨论专区
社区管理员
  • MySQL
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧