SQL使用IN进行分组统计时如何将不存在的字段显示为0

news2025/1/12 22:07:07

这两天被扔过来一个脏活儿:做一个试点运行系统的运营指标统计。

活儿之所以称为“脏”,是因为要统计8家单位共12个项目的指标。而每个项目有3个用户类指标,以及分17个功能模块,每个功能模块又分5个维度的指标。也就是单个项目是17 x 5 + 3 = 78个指标。总共78 x 12 = 936个。指标如下图所示:

在这里插入图片描述

交接人告知,实际上运营指标也才设计出来几天,相关开发工程师只给了几段SQL用来在数据库查询,至于说准确性啥的也不清楚。而看完统计演示,发现真的是最原始的“最粗最笨”的办法:每个项目通过6段SQL查询,然后完全人工在查询结果中挨个核对数据并填入excel报表!

疯了,一群草台班子!笔者当时的内心OS是这样的。

其中有关“当日活跃用户数(完成一笔有效业务交易,如单据提交或审批)”这个指标的,上图中标红字段,交接人表示开发人员反馈只能通过单位统计,无法通过项目来统计。而这一段SQL语句,需要手动替换单位编码,然后反复运行查询。代码如下:

#当日活跃用户数(完成一笔有效业务交易,如单据提交或审批)当日参与提交或审批人数

SELECT
         COUNT(DISTINCT h.USER_ID_)
FROM
        copro_bpm.copro_bpm_run_message r 
        LEFT JOIN copro_bpm.act_hi_comment h ON h.PROC_INST_ID_ = r.proc_inst_id
WHERE
		DATE(r.update_time) >=  DATE_SUB(CURDATE(), INTERVAL 1 DAY)
		AND DATE(r.update_time) <  CURDATE() 
        AND r.org_id in (387);

很容易想到的优化点是,将所有单位编码放到最后一句的IN关键字后面,如下:

#当日活跃用户数(完成一笔有效业务交易,如单据提交或审批)当日参与提交或审批人数

SELECT
org_id, CASE WHEN update_user IS NULL THEN 0 ELSE COUNT(DISTINCT update_user) END AS update_user_count
FROM
	copro_bpm.copro_bpm_run_message
WHERE
	DATE(update_time) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)
  AND org_id IN (387, 174, 165, 97, 157, 106, 133, 147)
GROUP BY
	org_id
ORDER BY
	org_id ASC;

然而运行测试发现一个问题:由于是按天来进行的统计,因此有些单位有时候这一天并没有数据,所以查询结果只显示了有数据的单位,类似下图:

在这里插入图片描述而这样一来,在excel中还是得人工去核对数据,不方便所有单位一起来复制粘贴。

因此,本文标题的解决的问题点来了:怎么将通过IN进行分组统计的结果中不存在的字段显示为0。结合这个情况,就是想办法将上面截图的结果中,未显示的其他单位编码和结果(显示为0)显示出来。

由于笔者平时使用SQL频率并不高,因此面对这个问题还是花了点儿时间解决。解决完后,始发现这应该是做指标统计的同学必然会遇到的一个常见问题。而解决办法也是一个必备经验。

下面的内容,希望给同样面对此种情况的朋友一些启发:

这个问题的根源,是因为通过where条件查询出的结果,只会显示存在的内容,不会显示不存在的内容。

笔者查看网上的帖子后,结合实践,目前找到两个好的办法:

一是通过LEFT JOIN,对于左表,不管右表有没有数据(对于上面的例子,假如IN后面的字段,有些不存在右表中;但都存在于左表中),那么不存在的单位相关字段(例子中是:update_user)将显示NULL,这样只要使用IFNULL将结果转为0即可达到目标。

但这个方法需要两个表,笔者这个例子中是使用一个表。应该可以构造一个临时表,作为右表。但笔者认为对于使用SQL不多的人,理解起来以及操作起来可能都相对要困难一些。

二是通过UNION ALL,将每个单位的结果组合起来。

最终,笔者使用了第二种方法,并稍做了改良。而这个改良的思路,笔者认为值得借鉴

就是构造每个单位的所要查询的内容都是0的临时表,然后通过UNION ALL与原正常查询的结果组合,这样得到的新表,将是IN后面所有单位都为0,再加上本来就有查询结果的单位,本例中就是截图中的org_id为133,结果为0这条数据。也就是说,因为UNION ALL不会去掉重复值(即org_id为133的两条数据,其中一条update_user为0,一条为3),而其他单位update_user是我们自己新构建的值0。这样,对于新表,再去按普通查询去查,将对org_id重复的进行合并,即org_id为133的合并显示为有值的3,其他不重复的显示为0。

通过这样的巧妙,也达成了目标。

写起来比较绕,但其实核心是理解解决方式的思路。思路了解后自己根据实际情况做调整,相信即可解决遇到的问题。

最后笔者改良后的代码如下:

#当日活跃用户数(完成一笔有效业务交易,如单据提交或审批)当日参与提交或审批人数

SELECT
org_id, update_user AS update_user_count
FROM
(SELECT 
org_id, COUNT(DISTINCT update_user) AS update_user
FROM
copro_bpm.copro_bpm_run_message
WHERE
	DATE(update_time) =  DATE_SUB(CURDATE(), INTERVAL 1 DAY)
  AND org_id IN (387, 174, 165, 97, 157, 106, 133, 147)
GROUP BY org_id
UNION ALL
SELECT 387 AS org_id, 0 AS update_user FROM DUAL
UNION ALL
SELECT 174 AS org_id, 0 AS update_user FROM DUAL
UNION ALL
SELECT 165 AS org_id, 0 AS update_user FROM DUAL
UNION ALL
SELECT 97 AS org_id, 0 AS update_user FROM DUAL
UNION ALL
SELECT 157 AS org_id, 0 AS update_user FROM DUAL
UNION ALL
SELECT 106 AS org_id, 0 AS update_user FROM DUAL
UNION ALL
SELECT 133 AS org_id, 0 AS update_user FROM DUAL
UNION ALL
SELECT 147 AS org_id, 0 AS update_user FROM DUAL) temp
GROUP BY org_id;

查询结果如下:

在这里插入图片描述笔者将上面截图的结果,全部复制粘贴进excel中,即可一次性做处理。能减少一些耗时,以及避免人工去比对数据所带来的可能的失误。

解决的办法,主要灵感得益于来自于知乎的一篇帖子,在此感谢。并将帖子链接粘贴如下,供参考:

《SQL分组统计把不存在的组计数为0》

以上,希望能帮到遇到同样问题的朋友;)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2131055.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

携手Vatee万腾平台,共赴智能时代新征程

在科技日新月异的今天&#xff0c;我们正站在一个前所未有的历史交汇点上——智能时代的大门已轰然洞开&#xff0c;万物互联、数据驱动、智能决策正逐步成为社会发展的新常态。在这场深刻的变革中&#xff0c;Vatee万腾平台以其前瞻性的视野、创新的技术实力以及深厚的行业积淀…

QtCreator学习(二).在stm32mp1中使用

0.配置编译环境 复制【正点原子】STM32MP157开发板&#xff08;A盘&#xff09;-基础资料\05、开发工具\01、交叉编译器st-example-image-qtwayland-openstlinux-weston-stm32mp1-x86_64-toolchain-3.1-snapshot.sh到虚拟机chmod添加可执行文件&#xff0c;./st*运行&#xff…

信号与线性系统综合实验

文章目录 一、实验目的二、实验内容及其结果分析&#xff08;一&#xff09;基础部分&#xff08;二&#xff09;拓展部分&#xff08;三&#xff09;应用设计部分 三、心得体会 一、实验目的 1、掌握连续时间信号与系统的时域、频域综合分析方法&#xff1b;   2、掌握运用M…

【数据库】MySQL-基础篇-多表查询

专栏文章索引&#xff1a;数据库 有问题可私聊&#xff1a;QQ&#xff1a;3375119339 目录 一、多表关系 1.一对多 2.多对多 3.一对一 二、多表查询概述 1.数据准备 2.概述 3.分类 三、内连接 1.隐式内连接 2.显式内连接 3.案例 四、外连接 1.左外连接 2.右外连…

力扣最热一百题——轮转数组

目录 题目链接&#xff1a;189. 轮转数组 - 力扣&#xff08;LeetCode&#xff09; 题目描述 示例 提示&#xff1a; 知识补充ArrayDeque &#xff08;&#xff09; ArrayDeque 的特点&#xff1a; 常用方法&#xff1a; 详细示例&#xff1a; 运行结果&#xff1a; …

无刷直流电动机的匝间绝缘测试优化

近年来&#xff0c;随着消费者对高效、快速干发需求的增加&#xff0c;高速电吹风逐渐成为市场的宠儿。高速电吹风的关键技术之一便是无刷直流电动机&#xff0c;其转速可以高达100,000转/分钟以上&#xff0c;电压为DC310V。相比传统电吹风&#xff0c;高速电吹风在效率和用户…

java基于PDF底层内容流的解析对文本内容进行编辑

本文实现了基于坐标位置对PDF内容的底层修改而非覆盖&#xff0c;因此不会出现在某些高级PDF编辑器中可以移除插入内容或者文件随着编辑次数增多而大幅增大&#xff08;原因是原内容还在文件中&#xff09;的问题&#xff0c;而且使用的pdfbox是一个开源的、免费的PDF处理库&am…

如何使用 Vidu Studio 根据照片和提示词生成视频

在这个数字化时代&#xff0c;视频内容已经成为我们日常生活中不可或缺的一部分。无论是记录美好瞬间&#xff0c;还是制作创意短片&#xff0c;视频都能生动地呈现我们的故事。今天&#xff0c;我将向大家介绍如何使用 Vidu Studio&#xff0c;根据已有照片和提示词&#xff0…

保姆级CVE-2018-17066漏洞复现 DLink命令注入漏洞(更新完结)

参考文章 CVE-2018-17066复现-CSDN博客 IOT-CVE-2018-17066(D-Link命令注入漏洞)_firmae路由仿真-CSDN博客 https://www.cnblogs.com/from-zero/p/13300396.html IOT-CVE-2018-17066(D-Link命令注入漏洞)_iot设备漏洞-CSDN博客 cve-2018-17066复现 | 1uckycs blog 漏洞环境搭建…

web渗透—RCE

一&#xff1a;代码执行 相关函数 1、eval()函数 assert()函数 (1)原理&#xff1a;将用户提交或者传递的字符串当作php代码执行 (2)passby:单引号绕过&#xff1a;闭合注释&#xff1b;开启GPC的话就无法绕过&#xff08;GPC就是将单引号转换为"反斜杠单引号"&a…

【Redis】缓存和数据库一致性问题及解决方案

往期文章&#xff1a; 【Redis】Redis 底层的数据结构&#xff08;结合源码&#xff09; 【Redis】为什么选择 Redis 做缓存&#xff1f; 【Redis】缓存击穿、缓存穿透、缓存雪崩原理以及多种解决方案 一、前言 在前面的文章中&#xff0c;我们探讨了为什么要使用 Redis…

独居打工人,把超市当顶配食堂

文 | 螳螂观察 作者 | 如意 独自在大城市扎根的年轻人有着自己的小确幸&#xff0c;比如“周末可以睡到下午才起床&#xff0c;不会有任何人打扰”&#xff0c;“瘫在沙发上吃着零食享受一部自己想看很久的电影&#xff0c;也不会被唠叨。” 但生活并不总是尽如人意&#xf…

基于SpringBoot+Vue的学生宿舍水电信息管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的…

PDF在线编辑哪家强?2024年4款热门工具大比拼

如今是数字化的时代&#xff0c;PDF 文件对我们工作和学习来说特别重要。不过呢&#xff0c;遇到那些麻烦的 PDF 编辑和转换的事情时&#xff0c;你是不是常常觉得没招儿&#xff0c;甚至还得加班到半夜&#xff1f;别犯愁啦&#xff0c;今天我给你讲讲四款非常好用的 PDF 在线…

深入理解全连接层:从线性代数到 PyTorch 中的 nn.Linear 和 nn.Parameter

文章目录 数学概念&#xff08;全连接层&#xff0c;线性层&#xff09;nn.Linear()nn.Parameter()Q1. 为什么 self.weight 的权重矩阵 shape 使用 ( out_features , in_features ) (\text{out\_features}, \text{in\_features}) (out_features,in_features)而不是 ( in_featur…

【人工智能】OpenAI最新发布的GPT-o1模型,和GPT-4o到底哪个更强?最新分析结果就在这里!

在人工智能的快速发展中&#xff0c;OpenAI的每一次新模型发布都引发了广泛的关注与讨论。2023年9月13日&#xff0c;OpenAI正式推出了名为o1的新模型&#xff0c;这一模型不仅是其系列“推理”模型中的首个代表&#xff0c;更是朝着类人人工智能迈进的重要一步。本文将综合分析…

10款超好用的电脑文件加密软件推荐|2024文件加密软件排行榜

在数字时代&#xff0c;数据安全已成为个人和企业不可忽视的重要议题。加密软件作为守护数据安全的坚固防线&#xff0c;其重要性不言而喻。以下是2024年备受推荐的十款电脑文件加密软件。 1.安秉网盾 安秉网盾以其全面的数据保护和安全防护功能备受企业青睐。它支持多种加密…

C语言内存函数(21)

文章目录 前言一、memcpy的使用和模拟实现二、memmove的使用和模拟实现三、memset函数的使用四、memcmp函数的使用总结 前言 正文开始&#xff0c;发车&#xff01; 一、memcpy的使用和模拟实现 函数模型&#xff1a;void* memcpy(void* destination, const void* source, size…

深入Redis:分布式锁

在一个分布式的系统中&#xff0c;会涉及到多个节点访问同一个公共资源的情况。此时就需要通过锁来做互斥控制&#xff0c;避免出现类似于“线程安全”的问题。 Java中的synchronize只能在当前线程中生效&#xff0c;在分布式的这种多个进程多个主机的场景下就无能为力了。此时…

原型模式详细介绍和代码实现

&#x1f3af; 设计模式专栏&#xff0c;持续更新中&#xff0c; 欢迎订阅&#xff1a;JAVA实现设计模式 &#x1f6e0;️ 希望小伙伴们一键三连&#xff0c;有问题私信都会回复&#xff0c;或者在评论区直接发言 Java实现原型模式 介绍: 原型模式&#xff08;Prototype Patte…