mysql通过某个字段分组统计数据

mysql通过某个固定状态字段分组统计数据, 字段状态不存在的统计数量为0

如下有个案例需求, 有如下user表, 需要根据status字段进行分组统计, 分别统计出: 待提交, 待审核, 通过, 驳回的条数, 以及每个状态的占比, 如果某个状态在数据库没有值, 则统计数量为0, 占比为0

在这里插入图片描述
创建user表的DDL语句如下

#创建表
create table user
(
    id        int auto_increment
        primary key,
    user_name varchar(20) null,
    money     int         null,
    password  varchar(30) null,
    status    char(1) comment '状态(0:待提交, 1:待审核, 2:通过, 3:驳回)');
#添加测试数据
INSERT INTO practice.user (id, user_name, money, password, status) VALUES (1, '李四', 100, null, '1');
INSERT INTO practice.user (id, user_name, money, password, status) VALUES (2, '李四', 100, null, '2');
INSERT INTO practice.user (id, user_name, money, password, status) VALUES (3, '张三', 500, null, '3');
INSERT INTO practice.user (id, user_name, money, password, status) VALUES (4, '张三', 500, null, '2');
INSERT INTO practice.user (id, user_name, money, password, status) VALUES (5, 'zs', 10000, '123', '1');
INSERT INTO practice.user (id, user_name, money, password, status) VALUES (6, 'ls', null, '123', '2');
INSERT INTO practice.user (id, user_name, money, password, status) VALUES (7, 'admin', null, '123', '2');
INSERT INTO practice.user (id, user_name, money, password, status) VALUES (8, 'ah', null, '123', '1');
INSERT INTO practice.user (id, user_name, money, password, status) VALUES (9, 'ahuo', null, '123', '3');
INSERT INTO practice.user (id, user_name, money, password, status) VALUES (10, '1', null, '123', '2');

拿到这个需求首先就是想到用group by, 但是对于我们刚刚入职没多久的小小程序员来说, 通过group by分组没有问题, 问题就在于如果某个状态在数据库中并没有值, 单纯使用group by无法筛选出无值的数据, 具体sql及结果如下
sql:

select COUNT(*) as num,
       status,
       round(COUNT(*) / (select count(*) as total from user where user_name is not null), 2) as persent
from user
where user_name is not null
group by status

执行结果:
在这里插入图片描述
果然, 我们发现当一种状态在数据库中不存在数据的时候, 单纯使用单表的group by无法实现我们的需求, 这个状态在数据库没有数据, 所以根本不会查出, 这违背了我们的需求, 如果我们把这种数据返回给前端, 你就等着前端妹妹来找你吧! 如果想要多聊天增进感情的算我没说(狗头滑稽)

那应该怎么做呢?
此处, 我给出一种解决办法

首先我们先按照我们想要的数据结构先拼接出一个表结构, 那我们想要的是什么结构呢, 当然是所有的status的状态是全的, 如下图所示, 请执行如下sql, 自行查看, 通过union all拼接出一个表结构当做主表然后关联一个子表写业务即可实现啦!

在这里插入图片描述

select '0' as status
      union all
      select '1' as status
      union all
      select '2' as status
      union all
      select '3' as status

最终sql如下, 如果大家有其他好的想法, 请评论留言! 本人一定好好学习! 谢谢!

select a.status,
       ifnull(b.num, 0)     as num,
       ifnull(b.persent, 0) as persent
from (select '0' as status
      union all
      select '1' as status
      union all
      select '2' as status
      union all
      select '3' as status) a
         left join (
    select COUNT(*) as num,
           status,
           round(COUNT(*) / (select count(*) as total from user where user_name is not null), 2) as persent
    from user
    where user_name is not null
    group by status
) b on a.status = b.status

完美解决~
在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值