• mysql group_concat


     

    group_concat()函数

     

    前言:在有group by的查询语句中,select指定的字段要么就包含在group by语句的后面,作为分组的依据,要么就包含在聚合函数中。(有关group by的知识请戳:浅析SQL中Group By的使用)。

     

    例5:

     

     

    该例查询了name相同的的人中最小的id。如果我们要查询name相同的人的所有的id呢?

     

    当然我们可以这样查询:

     

    例6:

     

     

    但是这样同一个名字出现多次,看上去非常不直观。有没有更直观的方法,既让每个名字都只出现一次,又能够显示所有的名字相同的人的id呢?——使用group_concat()

     

    1、功能:将group by产生的同一个分组中的值连接起来,返回一个字符串结果。

     

    2、语法:group_concat( [distinct] 要连接的字段 [order by 排序字段 asc/desc ] [separator '分隔符'] )

     

    说明:通过使用distinct可以排除重复值;如果希望对结果中的值进行排序,可以使用order by子句;separator是一个字符串值,缺省为一个逗号。

     

    3、举例:

     

    例7:使用group_concat()和group by显示相同名字的人的id号:

     

     

    例8:将上面的id号从大到小排序,且用'_'作为分隔符:

     

     

    例9:上面的查询中显示了以name分组的每组中所有的id。接下来我们要查询以name分组的所有组的id和score:

     

     
     
    =====================================================================================================

     

    以id分组,把price字段的值在一行打印出来,分号分隔 

    select id,group_concat(price separator ';') from goods group by id;  

    +------+----------------------------------+
    | id| group_concat(price separator ';') |
    +------+----------------------------------+
    |1 | 10;20;20 |
    |2 | 20|
    |3 | 200;500 |
    +------+----------------------------------+
    3 rows in set (0.00 sec)

    =============================================

    CREATE TABLE `grade1` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `stuName` varchar(22) DEFAULT NULL,
    `course` varchar(22) DEFAULT NULL,
    `score` int(11) DEFAULT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;

    -- ----------------------------
    -- Records of grade1
    -- ----------------------------
    INSERT INTO `grade1` VALUES ('1', '张三', '语文', '91');
    INSERT INTO `grade1` VALUES ('2', '张三', '数学', '90');
    INSERT INTO `grade1` VALUES ('3', '张三', '英语', '87');
    INSERT INTO `grade1` VALUES ('4', '李四', '语文', '79');
    INSERT INTO `grade1` VALUES ('5', '李四', '数学', '95');
    INSERT INTO `grade1` VALUES ('6', '李四', '英语', '80');
    INSERT INTO `grade1` VALUES ('7', '王五', '语文', '77');
    INSERT INTO `grade1` VALUES ('8', '王五', '数学', '81');
    INSERT INTO `grade1` VALUES ('9', '王五', '英语', '89'); 

    表内容如上图

    先看看group_concat语法:
    group_concat([DISTINCT] 要连接的字段 [Order BY ASC/DESC 排序字段] [Separator ‘分隔符’])

    以stuName分组,把score字段的值打印在一行,逗号分隔(默认)
    select GROUP_CONCAT(score),stuName from grade1 GROUP BY stuName;
    1
    2
    其结果是:


    那比如现在要查询出 语数外三门课的最低分,还有哪个学生考的?该怎么写??

    select GROUP_CONCAT(stuName ORDER BY score ASC),
    min(score) as score,
    course
    from
    grade1
    group by
    course;  
    其结果是:


    在结果中的第一列 ,有很多姓名并且以逗号隔开,其实这里的姓名就是按照score 升序排的(GROUP_CONCAT(stuName ORDER BY score ASC)),比如第一行的”王五,张三,李四”,就是按照数学的分数由低到高排序的,所以王五是数学分数最低的,那么我们只需要把这个字符串截取第一个人的名字就可以了,我们使用SUBSTRING_INDEX

    /*SUBSTRING_INDEX以逗号分隔,取第一个值*/
    select SUBSTRING_INDEX(GROUP_CONCAT(stuName ORDER BY score ASC),',',1),
    min(score) as score,
    course
    from
    grade1
    group by
    course;  
    其结果是:


    如果有并列最低分只能取到一个学生,可以这样修改,并列最低都可以查出:

    SELECT
    stuName,
    score,
    course
    FROM
    grade1
    WHERE
    (score, course) IN (
    SELECT
    min(score),
    course
    FROM
    grade1
    GROUP BY
    course
    ); 
    第一种如果有并列最低分只能取到一个学生,第二种没问题,不过效率可能会稍差点,数据量少就无所谓了

    还有一种写法(不知道效率怎么样):

    SELECT
    g.`id`,g.`course`,g.`score`,g.`stuName`
    FROM
    (SELECT
    course,
    SUBSTRING_INDEX(
    GROUP_CONCAT(score
    ORDER BY score ASC),
    ',',
    1
    ) AS score
    FROM
    grade1
    GROUP BY course) AS t
    LEFT JOIN grade1 AS g
    ON (
    t.course = g.`course`
    AND t.score = g.`score`
    )
    ---------------------  

    MySQL中group_concat函数


    完整的语法如下:


    group_concat([DISTINCT] 要连接的字段 [Order BY ASC/DESC 排序字段] [Separator '分隔符'])

     

    基本查询

     

    Sql代码  收藏代码
    1. select * from aa;  


    +------+------+
    | id| name |
    +------+------+
    |1 | 10|
    |1 | 20|
    |1 | 20|
    |2 | 20|
    |3 | 200 |
    |3 | 500 |
    +------+------+
    6 rows in set (0.00 sec)

     

    以id分组,把name字段的值打印在一行,逗号分隔(默认)

     

    Sql代码  收藏代码
    1. select id,group_concat(namefrom aa group by id;  


    +------+--------------------+
    | id| group_concat(name) |
    +------+--------------------+
    |1 | 10,20,20|
    |2 | 20 |
    |3 | 200,500|
    +------+--------------------+
    3 rows in set (0.00 sec)

     

    以id分组,把name字段的值打印在一行,分号分隔

     

    Java代码  收藏代码
    1. select id,group_concat(name separator ';') from aa group by id;  


    +------+----------------------------------+
    | id| group_concat(name separator ';') |
    +------+----------------------------------+
    |1 | 10;20;20 |
    |2 | 20|
    |3 | 200;500 |
    +------+----------------------------------+
    3 rows in set (0.00 sec)

     

    以id分组,把去冗余的name字段的值打印在一行,


    逗号分隔

     

    Sql代码  收藏代码
    1. select id,group_concat(distinct namefrom aa group by id;  


    +------+-----------------------------+
    | id| group_concat(distinct name) |
    +------+-----------------------------+
    |1 | 10,20|
    |2 | 20 |
    |3 | 200,500 |
    +------+-----------------------------+
    3 rows in set (0.00 sec)

     

    以id分组,把name字段的值打印在一行,逗号分隔,以name排倒序

     

    Sql代码  收藏代码
    1. select id,group_concat(name order by name descfrom aa group by id;  


    +------+---------------------------------------+
    | id| group_concat(name order by name desc) |
    +------+---------------------------------------+
    |1 | 20,20,10 |
    |2 | 20|
    |3 | 500,200|
    +------+---------------------------------------+
    3 rows in set (0.00 sec)

     

    测试sql,项目中用到的。

    Sql代码  收藏代码
    1. SELECT  
    2.         EMPLOYEES.EMPID  
    3.         ,EMPLOYEES.EMPNAME  
    4.         ,DEPARTMENTS.DEPARTMENTNAME  
    5.         ,EMPLOYEES.DEPTID  
    6.         ,EMPLOYEES.EMPPWD  
    7.         ,EMPLOYEES.INSIDEEMAIL  
    8.         ,EMPLOYEES.OUTSIDEEMAIL  
    9.         ,EMPLOYEES.DELEFLAG  
    10.         ,EMPLOYEES.EMPCLASS  
    11.         ,(CONCAT('[', <span style="color: #ff0000;">GROUP_CONCAT</span>  
    12. (ROLE.Role_Name SEPARATOR '],['), ']')) AS ROLENAME  
    13.         ,(concat( '[', (  
    14.             SELECT  
    15.                     <span style="color: #ff0000;">GROUP_CONCAT</span>  
    16. (DEPARTMENTS.DEPARTMENTNAME separator '],[')  
    17.                 FROM  
    18.                     EMP_ROLE_DEPT  
    19.                         LEFT JOIN DEPARTMENTS  
    20.                             ON (  
    21.                                 DEPARTMENTS.DEPARTMENTID = EMP_ROLE_DEPT.DEPTID  
    22.                                 AND DEPARTMENTS.DELEFLAG = 0  
    23.                             )  
    24.                 GROUP BY  
    25.                     EMP_ROLE_DEPT.EMPID  
    26.                 HAVING  
    27.                     EMP_ROLE_DEPT.EMPID = EMPLOYEES.EMPID  
    28.         ),']')) AS DEPARTMENTRIGHT  
    29.     FROM  
    30.         EMPLOYEES  
    31.             LEFT JOIN DEPARTMENTS  
    32.                 ON (  
    33.                     DEPARTMENTS.DEPARTMENTID = EMPLOYEES.DEPTID  
    34.                     AND DEPARTMENTS.DELEFLAG = 0  
    35.                 )  
    36.             LEFT JOIN ROLE_EMP  
    37.                 ON (ROLE_EMP.EMP_ID = EMPLOYEES.EMPID)  
    38.             LEFT JOIN ROLE  
    39.                 ON (ROLE_EMP.ROLE_ID = ROLE.ROLE_ID)  
    40. <span style="color: #ff0000;">    GROUP BY  
    41.         EMPLOYEES.EMPID</span>  
    42.   
    43.     HAVING  
    44.         EMPLOYEES.EMPID LIKE '%%'  
    45.         AND EMPLOYEES.EMPNAME LIKE '%%'  
    46.         AND EMPLOYEES.DELEFLAG = 0  
    47.         AND (  
    48.             EMPLOYEES.EMPCLASS = '1'  
    49.             OR EMPLOYEES.EMPCLASS = '2'  
    50.         )  
    51.         AND EMPLOYEES.DEPTID = '001' LIMIT 0  
    52.         ,16   
  • 相关阅读:
    并发编程(一)------同步类容器
    以邮件附件的形式发送测试报告
    Page Object 设计模式-PO
    生成Html 测试报告
    PHP 限制访问ip白名单
    PHP trait与单例模式 (一次编写,到处使用)
    ubuntu编译安装swoole (存多版本php时)
    ubuntu中apache的ssl证书配置及url重写
    如何在Ubuntu上在多个PHP版本之间切换 (for swoole)
    lamp项目上线流程简述 (ubuntu16.04 )
  • 原文地址:https://www.cnblogs.com/YuyuanNo1/p/10007056.html
Copyright © 2020-2023  润新知