关于MySQL中group by的一些问题的记录

only full group by问题的解约方案

这个报错的原因是,在SQL语句中,你查询的字段应该是你分组的依据,即selectcolumn应该全部跟在group by之后。这个也和MySQL的版本有关系,MySQL5.7版本默认设置了 mysql sql_mode = only_full_group_by 属性。
-- 如何查看MySQL的版本?
show variables like 'version';
-- 查看当前的sql_mode
show variables like 'sql_mode';

1. 懒省事做法-修改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';

2. 使用正确的SQL语句

2.1 从多个分组中各取1条数据

查询的字段需要全部作为分组的依据,但是实际情况下我们很多情况都是只根据一个字段来做分组,而且还需要对分组的数据进行某种规则的排序,来筛选出一条数据,那么可以通过如下SQL来实现:

select * from table_A a inner join 
(select col_1,max(col_2) col_2 from table_A group by col_1) tem 
on a.col_2 = tem.col_2

2.2 分组聚合排序

现在有表如下:

id person_name class_name group_size tag created_at updated_at
1 梁静涵 配电一班 3 system1 2025-02-13 10:00:00 2025-02-13 10:00:00
2 刘芷英 配电二班 3 system1 2025-02-13 10:00:00 2025-02-13 10:00:00
3 易琪千晨 配电三班 4 system2 2025-02-13 10:00:00 2025-02-13 10:00:00

目标是实现下面的需求

其中的 tag 是区分不同系统做数据隔离的作用。
那么实现分页的 sql 如下:

-- MySQL版本
SELECT class_name, COUNT(person_name) AS count, GROUP_CONCAT(person_name ORDER BY created_at ASC) AS group_members, max(updated_at) as time
FROM class_group
WHERE tag = 'system1'
GROUP BY class_name
ORDER BY time DESC

注意,ORDER BY 的字段必须出现在查询的字段中(没有怎么排序嘛)。

-- PG版本
SELECT class_name, COUNT(person_name) AS count, STRING_AGG(person_name, ',' ORDER BY created_at ASC) AS group_members, max(updated_at) as time
FROM class_group
WHERE tag = 'system1'
GROUP BY class_name
ORDER BY time DESC
posted @ 2022-01-10 15:25  大唐冠军侯  阅读(56)  评论(0)    收藏  举报