MySQL中将多行查询结果合并为一行展示SQL语句书写

MySQL中将多行查询结果合并为一行展示SQL语句书写

写在前面

  最近开发过程中,遇到一个需求是要将所查询的多条结果汇总成一条结果展示,由于之前没有接触过这方面的业务,所以经过一番折腾之后,解决了需求,这里特此记录一下,以供后续参考!

1、问题复现

这里以一个例子进行说明:

需求:一个员工每月是否完成了打卡,要求统计员工当月完成和未完成日期,展示结果如下:

<span>MySQL中将多行查询结果合并为一行展示SQL语句书写</span>

测试的数据库表字段如下:

CREATE TABLE `time_summary` (
  `id` int NOT NULL AUTO_INCREMENT,
  `emp_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '员工号',
  `emp_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '员工姓名',
  `time_date` date DEFAULT NULL COMMENT '填报日期',
  `finish_flag` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '完成标志:0:未完成,1:已完成',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

测试数据如下:

<span>MySQL中将多行查询结果合并为一行展示SQL语句书写</span>
<span>MySQL中将多行查询结果合并为一行展示SQL语句书写</span>

INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (1, '100', '张三', '2020-06-24', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (2, '100', '张三', '2020-06-23', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (3, '100', '张三', '2020-06-22', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (4, '100', '张三', '2020-06-19', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (5, '100', '张三', '2020-06-18', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (6, '100', '张三', '2020-06-17', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (7, '100', '张三', '2020-06-16', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (8, '100', '张三', '2020-06-15', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (9, '100', '张三', '2020-06-12', '1');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (10, '100', '张三', '2020-06-11', '1');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (11, '100', '张三', '2020-06-10', '1');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (12, '100', '张三', '2020-06-09', '1');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (13, '100', '张三', '2020-06-08', '1');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (14, '100', '张三', '2020-06-05', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (15, '100', '张三', '2020-06-04', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (16, '100', '张三', '2020-06-03', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (17, '100', '张三', '2020-06-02', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (18, '100', '张三', '2020-06-01', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (19, '101', '李四', '2020-06-24', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (20, '101', '李四', '2020-06-23', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (21, '101', '李四', '2020-06-22', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (22, '101', '李四', '2020-06-19', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (23, '101', '李四', '2020-06-18', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (24, '101', '李四', '2020-06-17', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (25, '101', '李四', '2020-06-16', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (26, '101', '李四', '2020-06-15', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (27, '101', '李四', '2020-06-12', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (28, '101', '李四', '2020-06-11', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (29, '101', '李四', '2020-06-10', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (30, '101', '李四', '2020-06-09', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (31, '101', '李四', '2020-06-08', '1');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (32, '101', '李四', '2020-06-05', '1');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (33, '101', '李四', '2020-06-04', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (34, '101', '李四', '2020-06-03', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (35, '101', '李四', '2020-06-02', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (36, '101', '李四', '2020-06-01', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (37, '102', '王五', '2020-06-24', '1');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (38, '102', '王五', '2020-06-23', '1');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (39, '102', '王五', '2020-06-22', '1');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (40, '102', '王五', '2020-06-19', '1');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (41, '102', '王五', '2020-06-18', '1');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (42, '102', '王五', '2020-06-17', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (43, '102', '王五', '2020-06-16', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (44, '102', '王五', '2020-06-15', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (45, '102', '王五', '2020-06-12', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (46, '102', '王五', '2020-06-11', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (47, '102', '王五', '2020-06-10', '1');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (48, '102', '王五', '2020-06-09', '1');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (49, '102', '王五', '2020-06-08', '1');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (50, '102', '王五', '2020-06-05', '1');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (51, '102', '王五', '2020-06-04', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (52, '102', '王五', '2020-06-03', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (53, '102', '王五', '2020-06-02', '0');
INSERT INTO `time_summary`(`id`, `emp_id`, `emp_name`, `time_date`, `finish_flag`) VALUES (54, '102', '王五', '2020-06-01', '0');

View Code

这种情况下,我们一般可以将所有的情况查询出来(这里以6月份数据为例),查询SQL如下:

SELECT t.emp_id,t.emp_name,t.time_date,t.finish_flag from time_summary t 
where t.time_date >= '2020-06-01' and time_date <= '2020-06-30'

这样查询的结果如下:

<span>MySQL中将多行查询结果合并为一行展示SQL语句书写</span>

 这种显然不满足要求,针对这种情况,要怎么做呢?

 2、问题解决

这时候需要使用 GROUP_CONCAT() 函数解决此问题。

说明:

1.GROUP_CONCAT() 中的值为你要合并的数据的字段名;

 SEPARATOR 函数是用来分隔这些要合并的数据的,默认以 逗号 分隔;

 ' '中是你要用哪个符号来分隔;

2.必须要用GROUP BY 语句来进行分组管理,不然所有的数据都会被合并成一条记录

则此处对应的SQL语句如下,仅供参考!

SELECT
    su.emp_id,
    su.emp_name,
    a.notFinished,
    b.finished 
FROM
    (
    SELECT
        t.emp_id,
        t.emp_name 
    FROM
        time_summary t 
    WHERE
        t.time_date >= '2020-06-01' 
        AND t.time_date <= '2020-06-30' 
    GROUP BY
        t.emp_id,
        t.emp_name 
    ) su
    LEFT JOIN (
    SELECT
        t.emp_id,
        t.emp_name,
        GROUP_CONCAT( SUBSTRING( t.time_date, 9, 2 ) SEPARATOR ',' ) AS notFinished 
    FROM
        time_summary t 
    WHERE
        t.time_date >= '2020-06-01' 
        AND t.time_date <= '2020-06-30' 
        AND t.finish_flag = '0' 
    GROUP BY
        t.emp_id,
        t.emp_name 
    ) a ON su.emp_id = a.emp_id
    LEFT JOIN (
    SELECT
        t.emp_id,
        t.emp_name,
        GROUP_CONCAT( SUBSTRING( t.time_date, 9, 2 ) SEPARATOR ',' ) AS finished 
    FROM
        time_summary t 
    WHERE
        t.time_date >= '2020-06-01' 
        AND t.time_date <= '2020-06-30' 
        AND t.finish_flag = '1' 
    GROUP BY
        t.emp_id,
        t.emp_name 
    ) b ON su.emp_id = b.emp_id

3、内容扩展

在MySQL中字符串拼接常用的方法整理:
 1、CONCAT()
 2、CONCAT_WS()
 3、GROUP_CONCAT()

3.1 CONCAT()

语法:CONCAT(str1,str2,...)
说明:作为最常用的字符串拼接方法,但是CONCAT函数在遇到拼接中的字符串出现 NULL 的情况,会返回 NULL

示例:

<span>MySQL中将多行查询结果合并为一行展示SQL语句书写</span>

3.2 CONCAT_WS()

此种连接字符串的方法,从名字上就能看出:从concat with separator,使用分隔符连接字符串。

语法:CONCAT_WS(separator,str1,str2,…)
使用说明:第一个参数separator是用来分隔其它参数的分隔符。分隔符的位置放在要连接的两个字符串之间。分隔符可以是一个字符串,也可以是其它参数
对比说明:concat_ws与concat相比优点:
         1、可以使用分隔符连接字符串
         2、若连接的字符串出现 NULL 值,concat_ws会忽略 NULL 值,
            返回其他连接字符串

示例1:

<span>MySQL中将多行查询结果合并为一行展示SQL语句书写</span>

示例2:

 <span>MySQL中将多行查询结果合并为一行展示SQL语句书写</span>

3.3 GROUP_CONCAT()

此种连接方法,主要是将某一字段的值连接成一行进行显示,具体可以参看上面的问题实例。

语法 :group_concat( [DISTINCT] 连接的字段 [Order BY 排序字段 ASC/DESC] [Separator ‘分隔符’] )
说明:可以连接多个字段,也可以对连接字段进行排序,默认以 逗号 分隔字段
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/2244.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 按位异或的深入理解[通俗易懂]

    按位异或的深入理解[通俗易懂]异或运算:首先异或表示当两个数的二进制表示,进行异或运算时,当前位的两个二进制表示不同则为1相同则为0.该方法被广泛推广用来统计一个数的1的位数!参与运算的两个值,如果两个相应bit位相同,则结果为0,否则为1。即:  0^0=0,   1^0=1,   0^1=1,   1^1=0按位异或的3个特点:(1)0^0=0,0^1=1 0

  • eplan激活码破解步骤【2021最新】

    (eplan激活码破解步骤)JetBrains旗下有多款编译器工具(如:IntelliJ、WebStorm、PyCharm等)在各编程领域几乎都占据了垄断地位。建立在开源IntelliJ平台之上,过去15年以来,JetBrains一直在不断发展和完善这个平台。这个平台可以针对您的开发工作流进行微调并且能够提供…

  • chrome弱网_弱网测试参考

    弱网测试要点方法方法一:利用抓包工具charles进行弱网设置,适用PC端和移动端(IOS/Android)1.以charles4.0版本为例,打开Proxy->ThrottleSettings2.打开ThrottleSettings界面如下3.charles的预设已经有常用的网速模拟设置,根据需要设置即可,当然也可以自己添加预设,自己去研究吧。PS:fiddle抓包弱网模拟,Face…

  • networkmanager配置文件_conf文件可以删除吗

    networkmanager配置文件_conf文件可以删除吗NameNetworkManager.conf-NetworkManagerconfigurationfileSynopsis/etc/NetworkManager/NetworkManager.confor/NetworkManager/NetworkManager.confwheredependsonyourdistributionorbuild.

  • asp.net页面的AutoEventWireup=”true”属性设置

    asp.net页面的AutoEventWireup=”true”属性设置1、如果设置AutoEventWireup=”true”,那么页面首次加载的时候isPostback=false;会自动执行Page_Load方法触发页面的事件时(如按钮单击),也会先执行Page_Load方法(只是这个时候的isPostback=true),接着再去执行对应的事件2、如果设置AutoEventWireup=”false”,那么Page_Load方法将不会被执行,触发页面的事

  • tomcat内存溢出,应用进程死锁

    tomcat内存溢出,应用进程死锁

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号