相关文章推荐
考研的松树  ·  mysqldump - ...·  1 周前    · 
爱运动的手电筒  ·  RDS ...·  3 天前    · 
长情的火锅  ·  java - Collectors ...·  9 月前    · 
爽快的花卷  ·  Execute a batch file ...·  1 年前    · 

这是我参与2022首次更文挑战的第23天,活动详情查看: 2022首次更文挑战

MySQL 是后端开发必懂必会的数据库系统,实际使用时根据数据库的相关语法和 SQL 语句操作数据,而对数据的分组处理大部分是在使用 GROUP BY 语句。

1. GROUP BY

1.1 根据指定字段分组查询

group by [field],根据指定的列进行分组(相同组的数据合并,保留第一项),可以和sum()、count()、min()、max()等组合函数同时使用,来获取当前组保留字段值的和、数量、最大或最小值。

1.2 指定多个字段分组查询

根据多个字段分组时,只需要在 group by 关键字之后使用 , 间隔多个数据表列名即可。如根据省、市、区分组筛选客户数据可以写为:

SELECT * FROM customer group by province, city, area;

在查询数据时,想要根据多个字段对数据去重时,group by 比 distinct 关键字更好用。

2. GROUP_CONCAT

对于同一组中的数据,需要将指定字段的内容全部显示而不是仅展示组内第一条内容时,可以使用group_concat(field) 函数,该函数可以将同组内所有数据在该列的值进行拼接展示。

2.1 规范

group_concat( [distinct] [field] [order by field asc/desc ] [separator '分隔符'] )

  • distinct 关键字可以排除拼接字段中的重复值
  • order by 子句可以对结果中的值进行排序后拼接
  • separator是一个字符串值,缺省时默认使用逗号分隔
  • 2.2 使用

    使用group by根据指定列分组,返回结果时使用group_concat拼接同组的结果值

    select *, group_concat(name) as names from customer group by province, city ;
    

    3. 使用Group By分组时自定义显示哪一条数据

    group by 在根据指定数据列分组时,会将同一组的字段值进行合并,最终仅展示默认第一条数据的值,如果需要指定分组后显示哪一条数据值,应该如何操作?

    3.1 排序后分组

    如果分组筛选数据时希望指定显示字段内容,而不是默认的展示第一条数据值,比如展示该组数据中最新的一条数据,这个时候可以先对数据使用时间字段排序,然后再进行分组。

    SELECT * FROM (SELECT * from customer ORDER BY date desc) a GROUP BY province, city;
    

    该方法在 MySQL5.7 和之前版本中是有效的,但是在之后更高版本中,由于MySQL的优化处理,导致单纯的排序行为在之后的group by中无效化了。

    3.2 排序后获取数据再分组

    MySQL 的优化导致单纯排序不再生效,但是如果我们根据排序的结果获取其中数据,此时得到的结果就是有序的,再使用group by分组时,就会保持已有的顺序,这在高版本MySQL中也可以作为一种方法。

    SELECT * FROM (SELECT * from customer ORDER BY date desc limit 1000) a GROUP BY province, city;
    

    但是在实际的查询过程中,往往是只需要分组,而不需要根据排序获取内容,因此该方法适用性不强。

    3.3 组合函数

    还有另外一种更加稳定的方法,可以指定分组后展示的数据值,即使用 group by 配合组合函数的方式先获取到某个字段的期望数据,然后再使用该字段数据与原数据表关联查询,最终得到按照该字段筛选出的结果。

    如果当前字段不能严格区分多条数据,如有相同的,则仍会优先取相同数据的第一条,此时数据值是相同的,最终效果相同。

    # 表链接查询方式
    select CustomerCode from customer c1
    inner join (
        SELECT  max(date_time) as date_time FROM customer 
        group by CustomerCode
    on c1.date_time = c2.date_time
    # 多表查询,将分组后的字段作为新表
    select * from Customer c1 , (SELECT  max(date_time) as date_time FROM customer group by CustomerCode) c2
    where c1.date_time = c2.date_time
    # 子查询方式
    select * from Customer c1 where c1.date_time in (SELECT  max(date_time) as date_time FROM customer group by CustomerCode)
    
  • 实际使用时更推荐使用表连接方式查询,sql语句易懂且查询性能较优。
  • 刀斧手何在 MySQL
    私信