mysql常用函数之group_concat()、group by、count()、case when then的使用
拄杖忙学轻声码 人气:0场景:
在mysql的关联查询或子查询中,函数 group_concat(arg) 可以合并多行的某列(或多列)数据为一行,默认以逗号分隔。以及分组函数和统计函数的组合使用
测试数据准备:
一、行转列函数 group_concat(arg)
1、单列合并,默认以逗号分隔
select group_concat(ttop.user_name) as testStr from t_table_one_parent ttop;
输出:
张三1,张三2,张三3,张三1,张三2,张三3,张三4
2、单列合并,指定冒号分隔符
select group_concat(ttop.user_name separator ';') as testStr from t_table_one_parent ttop;
输出:
张三1;张三2;张三3;张三1;张三2;张三3;张三4
3、单列合并,并去重
select group_concat(distinct ttop.user_name separator ';') as testStr from t_table_one_parent ttop;
输出:
张三1;张三2;张三3;张三4
4、多列拼接合并
select group_concat(distinct ttop.user_name, ttop.company_code separator ';') as testStr from t_table_one_parent ttop;
输出:
张三1123456;张三21234567;张三312345678;张三4123456789
5、多列拼接合并,列和列之间指定分隔符
select group_concat(distinct ttop.user_name, ',', ttop.company_code separator ';') as testStr from t_table_one_parent ttop;
输出:
张三1,123456;张三2,1234567;张三3,12345678;张三4,123456789
小结:
1、group_concat() 函数默认合并后以逗号分隔,也可以自定义分隔符
2、group_concat() 函数可以多列合并,列和列之间可以自定义分隔符
3、group_concat() 函数可以使用 distinct 进行去重合并
二、分组 group by、count()、sum() 函数的组合使用
1、分组和统计
select user_name as userName, count(user_name) as ctUserName from t_table_one_parent ttop group by user_name;
输出:
2、分组和求和
select user_name as userName, count(user_name) as ctUserName, sum(total_account_balance) as sumTab from t_table_one_parent ttop group by user_name;
输出:
小结:
1、group by 分组可以配合 count() 统计函数综合使用,输出每组中的数量
2、group by 分组可以配合 sum() 求和函数综合使用,输出每组中的数字的和
3、group by 分组可以配合 count()、sum() 一起使用,输出每组中的数量以及和
三、count() 配合 case when then 的使用
脚本备份:
create table if not exists t_department_info ( id bigint not null primary key auto_increment comment '主键id', dept_name varchar(50) not null comment '部门名称', dept_director varchar(20) not null comment '部门主管', create_by bigint comment '创建人Id', create_date datetime not null default now() comment '创建时间', update_by bigint comment '更新人Id', update_date datetime not null default now() on update now() comment '更新时间' ) engine = InnoDB auto_increment = 1 default charset = utf8 comment '部门信息表'; create table if not exists t_person_info ( id bigint not null primary key auto_increment comment '主键id', person_name varchar(10) not null comment '人员名称', id_number varchar(50) not null comment '省份证号', gender varchar(5) not null comment '性别,M男、F女', induction_date datetime null comment '入职日期', quit_date datetime null comment '离职日期', if_on_job tinyint(1) default 1 comment '是否在职状态,0-否,1-是', dept_id bigint null comment '部门Id', create_by bigint comment '创建人Id', create_date datetime not null default now() comment '创建时间', update_by bigint comment '更新人Id', update_date datetime not null default now() on update now() comment '更新时间' ) engine = InnoDB auto_increment = 1 default charset = utf8 comment '人员资料信息表'; -- 写入数据 INSERT INTO any_case.t_department_info (id, dept_name, dept_director, create_by, create_date, update_by, update_date) VALUES (1, '研发部', '张三', 1, '2022-12-22 16:38:10', null, '2022-12-22 16:38:10'); INSERT INTO any_case.t_department_info (id, dept_name, dept_director, create_by, create_date, update_by, update_date) VALUES (2, '测试部', '张三', 1, '2022-12-22 16:38:10', null, '2022-12-22 16:38:10'); INSERT INTO any_case.t_department_info (id, dept_name, dept_director, create_by, create_date, update_by, update_date) VALUES (3, '运维部', '李四', 1, '2022-12-22 16:38:10', null, '2022-12-22 16:38:10'); INSERT INTO any_case.t_person_info (id, person_name, id_number, gender, induction_date, quit_date, if_on_job, dept_id, create_by, create_date, update_by, update_date) VALUES (1, '张三', '123456789987654321', 'M', '2022-11-23 00:40:35', null, 1, 1, 1, '2022-12-22 16:40:48', null, '2022-12-22 16:40:48'); INSERT INTO any_case.t_person_info (id, person_name, id_number, gender, induction_date, quit_date, if_on_job, dept_id, create_by, create_date, update_by, update_date) VALUES (2, '李四', '123456789987654321', 'F', '2022-11-23 00:40:35', '2022-12-23 00:54:47', 0, 1, 1, '2022-12-22 16:40:48', null, '2022-12-22 16:54:40'); INSERT INTO any_case.t_person_info (id, person_name, id_number, gender, induction_date, quit_date, if_on_job, dept_id, create_by, create_date, update_by, update_date) VALUES (3, '王五', '123456789987654321', 'M', '2022-11-23 00:40:35', '2022-11-30 00:54:54', 0, 1, 1, '2022-12-22 16:40:48', null, '2022-12-23 02:13:29'); INSERT INTO any_case.t_person_info (id, person_name, id_number, gender, induction_date, quit_date, if_on_job, dept_id, create_by, create_date, update_by, update_date) VALUES (4, '赵六', '123456789987654321', 'F', '2022-11-23 00:40:35', null, 1, 2, 1, '2022-12-22 16:40:48', null, '2022-12-22 16:40:48'); INSERT INTO any_case.t_person_info (id, person_name, id_number, gender, induction_date, quit_date, if_on_job, dept_id, create_by, create_date, update_by, update_date) VALUES (5, '李七', '123456789987654321', 'M', '2022-11-23 00:40:35', null, 1, 2, 1, '2022-12-22 16:40:48', null, '2022-12-22 16:40:48'); INSERT INTO any_case.t_person_info (id, person_name, id_number, gender, induction_date, quit_date, if_on_job, dept_id, create_by, create_date, update_by, update_date) VALUES (6, '郑八', '123456789987654321', 'F', '2022-11-23 00:40:35', null, 1, 1, 1, '2022-12-22 16:41:17', null, '2022-12-22 17:00:22');
1、主从表关联查询统计示例脚本
select tdi.dept_name, tdi.dept_director ,count(tpi.id) as allPersonNum -- 全部人数 ,count(case when tpi.if_on_job = 1 then tpi.id end) as ifOnJobNum -- 在职全部人数 ,count(case when tpi.if_on_job = 1 and tpi.gender = 'M' then tpi.id end) as ifOnJobMNum -- 在职男性人数 ,count(case when tpi.if_on_job = 1 and tpi.gender = 'F' then tpi.id end) as ifOnJobFNum -- 在职女性人数 ,count(case when tpi.if_on_job = 0 then tpi.id end) as quitNum -- 离职总人数 ,count(case when tpi.if_on_job = 0 and date_format(tpi.quit_date, '%Y-%m') = date_format(now(), '%Y-%m') then tpi.id end) as quitNumThisMonth -- 本月离职人数 from t_department_info tdi left join t_person_info tpi on tpi.dept_id = tdi.id #支持主表和从表过滤 where tdi.dept_director like '%张%' and (tpi.if_on_job = 0 and date_format(tpi.quit_date, '%Y-%m') = date_format(now(), '%Y-%m')) > 0 and tpi.person_name like '%李%' group by tdi.dept_name, tdi.dept_director;
可见主与从表关系为一对多,而查询列中的 count() 中根据从表中的条件来判断是否统计入该条数据,符合条件的话返回给 count() 统计依据列,不符合条件返回给 count() 统计依据为 null(默认null不统计)
2、这样写的好处比关联多个 left join 对象这种方式的查询效率要快很多,而且还简洁明了不混乱
加载全部内容