Mysql 使用 GROUP BY 查询

Mysql 使用 GROUP BY 查询

IILee 15 2022-07-18

前言

Mysql 到 5.7 版本以后就默认禁用了 GROUP BY 的直接查询,必须使用 ANY_VALUE 函数才能使用。

内容

  • 新建一张表:
CREATE TABLE LSQ_TEST_TABLE (
        ID VARCHAR(64) NOT NULL COMMENT '主键',
        NAME VARCHAR(10) COMMENT '姓名',
        CLASS VARCHAR(10) COMMENT '班级',
        YUWEN VARCHAR(10) COMMENT '语文',
        SHUXUE VARCHAR(10) COMMENT '数学',
        ENGLISH VARCHAR(10) COMMENT '英语',
        PHYSICS VARCHAR(10) COMMENT '物理',
        CREATTIME VARCHAR(19) COMMENT '创建时间',
        PRIMARY KEY (ID),
        INDEX IDX_NAME (NAME)
    )ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='测试表';

插入几条数据后,查询结果:

image

现在我的查询需求是得到 NAME 和 YUWEN 去重的结果。

  • group by 或者 distinct 分组

传统的办法是采用 group by 或者 distinct 关键字,看下面:

select NAME, YUWEN FROM lsqsit.lsq_test_table GROUP BY NAME, YUWEN;
select distinct NAME,YUWEN FROM lsqsit.lsq_test_table ;

两条 SQL 执行结果都为:

image

这种方式的缺点是无法得到其他字段的值。

下面有两种方式可以解决这个缺点:

  • 方法 1:使用 ANY_VALUE() 字段

SQL 如下:

SELECT ANY_VALUE(ID),ANY_VALUE(NAME),ANY_VALUE(YUWEN),ANY_VALUE(ENGLISH),ANY_VALUE(SHUXUE),ANY_VALUE(PHYSICS),ANY_VALUE(CREATETIME) FROM lsq_test_table where lsq_test_table.CLASS = "1" GROUP BY NAME, YUWEN;

这个查询到的结果为:

image

  • 方法 2:使用组合查询

思路是:①首先根据排重字段 NAME 和 YUWEN 进行 group by,然后对 group by 的每个结果去最大 id,即 MAX(id);②然后从主表中找到这些 id 的记录

SELECT id,name,yuwen,shuxue,english,physics,createTime FROM lsq_test_table WHERE id 

IN(SELECT MAX(id) FROM lsq_test_table where CLASS = "1" GROUP BY NAME, YUWEN)

image

注意:发现重复的记录取的是 id 最大的那个。

两个方法对比: 方法 1 只会对数据库查询一次,而方法 2 会查询库两次; 方法 2 中 in() 函数没有索引,因此如果你 id 数量足够多的话,那么查询会很慢;

后记

原文地址: www.liflag.cn