一张表中几列字段以不同的条件规则去统计计数展示实现思路设计

news2024/10/7 2:18:35

今天在写一个业务的时候,遇到这样一个需求

一、需求描述

一张表中其中几列字段需要以不同的条件规则去统计计数,求实现方式

因为项目业务涉及隐私,我就想了一个类似的情景

二、情景描述

有一张月考成绩表,包含学生和他的各科成绩
在这里插入图片描述
现在需要生成一张统计表,统计各月份 各班级 各科成绩高于80的人数

如:

月考月份班级语文数学英语物理
2023-0730118242715
2023-07302270330
2023-0730316131921

注意:

1、月考不是强制要求,以班级为单位,会存在某月某一班级没参加月考的情况,如303班在6月没参与考试
2、会存在某一班级某一学科成绩没有超过80分的情况

分析发现,表中存有不同班级不同月份的成绩数据,科目不只一个,如果想使用sql语句来实现的话,一个sql语句只能查询出一个科目满足要求的人数,
如:

select count(math) math,yearmonth,classroom from stu_score where math>80 
 	group by yearmonth,classroom

这个sql只能查询各班级各月份一个科目(数学)统计的人数
那么执行多条sql来查询出各科成绩人数再拼接起来(通过月份和班级关联)

如果数据很规范的话,这样处理没有问题,可是注意中2个条件让问题增加了难度

三、展开细节

查询各科人数数据,你会发现

select count(math) math,yearmonth,classroom from stu_score where math>80 
group by yearmonth,classroom

在这里插入图片描述

select count(chinese) chinese,yearmonth,classroom from stu_score where chinese>80 
group by yearmonth,classroom

在这里插入图片描述

select count(english) english,yearmonth,classroom from stu_score where english>80 
group by yearmonth,classroom

在这里插入图片描述

select count(physics) physics,yearmonth,classroom from stu_score where physics>80 
group by yearmonth,classroom

在这里插入图片描述

四、解决问题方向

如何把查询出来的4个数据结果存放到一张表中,这是我们需要解决的问题

方案探讨

有人会说,这简单,根据yearmonth,classroom这2个字段来关联,4张表多表查询实现就好了
但观察会发现,4组查询出来的数据,yearmonth,classroom进行关联,会存在部分数据无法连接查询

如观察英语和语文查询出来的数据
在这里插入图片描述
对于上面的数据,我们希望查询的结果是

yearmonthclassroomEnglishchinese
2023-0730221
2023-0730174
2023-0730310
2023-0630101

发现303班7月有英语人数,但没有语文人数

也就是说如果以英语表作为主表外左连接那么无法查询出这种效果(外连接需要关联yearmonth,classroom,以其中一个表作主表进行外连接,都会丢失第3或第4条数据)

有人会说,用笛卡尔积,这种方式更没有实际意义,会查出3*3=9条数据,但数据无意义且不正确

然后我想着Java结合sql语句的方式来实现这个过程:
下面是我2个思路:

思路一

把查询出来的各科人数存入多个集合中,再准备一个汇总集合,把分散的学科集合都添加到汇总集合中,这样汇总集合里数据就是需要的统计数据

这个思路想法很好,但在代码实现的过程中发现,实现难度较大,最后放弃了,但我还是说一下实现过程:

1、把查询出来的各科人数存入集合中,题目中有4个科目,那么就存入4个list集合a,b,c,d

list的泛型是自定义的dto

@Data
public class ScoreStatDto {
    private String yearmonth;
    private String classroom;
    private String chinese;
    private String math;
    private String english;
    private String physics;
}

每个集合中3个元素会赋值,yearmonth,classroom和对应学科

2、获取最长的那个集合长度

3、按这个长度进行循环遍历,在遍历过程中有值就赋值

for(int i=0;i<max;i++){
    ScoreStatDto dto = new ScoreStatDto();
    if(a.size() <=i){
        //集合已经遍历完
    }else{
        dto.set科目1(a.get(i).get科目1());
        if(b.size() <= i){
            //嵌套4个if
            ...
        }
    }
}

这样写出来的代码不仅丑陋,而且也存在问题,科目a和科目b查出来的数据yearmonth,classroom不一定一一对应,如:
在这里插入图片描述
那又得加判断逻辑,很麻烦繁琐,所以pass

思路二:

拿到集合数据,依次存入一张新表中,存入规则为:以yearmonth,classroom为联合主键,如果没有就新增,如果有则更新,存入完成后即为需要的统计结果

1、还是存到4个集合中,再把4个集合存入一张新表中score_stat,新表表结构为:

yearmonth,classroom,和各科科目人数,yearmonth,classroom是联合主键
在这里插入图片描述

2、存入数据的方式:如果有yearmonth,classroom都一样的,那么更新这条记录(也就完成了科目的拼接),如果没有,那么新增

这种存数据的方式sql是可以实现的:

INSERT INTO score_stat (yearmonth, classroom, chinese) 
	values(:yearmonth, :classroom, :chinese) 
ON DUPLICATE KEY UPDATE 
	yearmonth = VALUES(yearmonth),
	classroom = VALUES(classroom),
	chinese = VALUES(chinese)

那么4个科目对应4个集合那就需要4个sql来完成

3、插入完成后,score_stat表即为目标数据

五、小结:

  • 在实现业务逻辑的时候,不一定非要一个sql语句来解决业务要求,可以试着对需求进行拆分,也可以试着开发语言与sql语句结合的方式来共同完成需求的实现;
  • 使用复杂的sql语句可能会降低性能;
  • 可以考虑将查询的数据存入新表中;

ps: 思路二上的sql还是chatgpt教我的,真的是大大提高了生产力 ψ(`∇´)ψ
在这里插入图片描述
如果同学们想要复现上述情景,资料如下:

1、成绩表

DROP TABLE IF EXISTS `stu_score`;
CREATE TABLE `stu_score`  (
  `stuname` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '学生姓名',
  `chinese` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '语文',
  `math` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '数学',
  `English` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '英语',
  `physics` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '物理',
  `classroom` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '班级',
  `yearmonth` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '年月'
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '学生成绩表' ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of stu_score
-- ----------------------------
INSERT INTO `stu_score` VALUES ('李四1', '98', '100', '89', '50', '302', '2023-07');
INSERT INTO `stu_score` VALUES ('王五1', '72', '76', '80', '59', '302', '2023-07');
INSERT INTO `stu_score` VALUES ('赵六1', '66', '78', '99', '100', '302', '2023-07');
INSERT INTO `stu_score` VALUES ('张三1', '80', '95', '76', '92', '302', '2023-07');
INSERT INTO `stu_score` VALUES ('张三2', '80', '95', '76', '92', '301', '2023-06');
INSERT INTO `stu_score` VALUES ('李四2', '98', '100', '79', '50', '301', '2023-06');
INSERT INTO `stu_score` VALUES ('王五2', '72', '76', '66', '59', '301', '2023-06');
INSERT INTO `stu_score` VALUES ('赵六2', '66', '78', '79', '100', '301', '2023-06');
INSERT INTO `stu_score` VALUES ('张三3', '80', '95', '76', '92', '301', '2023-06');
INSERT INTO `stu_score` VALUES ('李四3', '98', '100', '89', '50', '301', '2023-07');
INSERT INTO `stu_score` VALUES ('王五3', '72', '76', '80', '59', '301', '2023-07');
INSERT INTO `stu_score` VALUES ('赵六3', '66', '78', '99', '100', '301', '2023-07');
INSERT INTO `stu_score` VALUES ('张三4', '80', '95', '76', '92', '301', '2023-07');
INSERT INTO `stu_score` VALUES ('李四4', '98', '100', '89', '50', '301', '2023-07');
INSERT INTO `stu_score` VALUES ('王五4', '72', '76', '80', '59', '301', '2023-07');
INSERT INTO `stu_score` VALUES ('赵六4', '66', '78', '99', '100', '301', '2023-07');
INSERT INTO `stu_score` VALUES ('张三5', '80', '95', '76', '92', '301', '2023-07');
INSERT INTO `stu_score` VALUES ('李四5', '98', '100', '89', '50', '301', '2023-07');
INSERT INTO `stu_score` VALUES ('王五5', '72', '76', '80', '59', '301', '2023-07');
INSERT INTO `stu_score` VALUES ('赵六5', '66', '78', '99', '100', '301', '2023-07');
INSERT INTO `stu_score` VALUES ('张三', '80', '95', '76', '92', '301', '2023-07');
INSERT INTO `stu_score` VALUES ('李四', '98', '100', '89', '50', '301', '2023-07');
INSERT INTO `stu_score` VALUES ('王五', '72', '76', '80', '59', '303', '2023-07');
INSERT INTO `stu_score` VALUES ('赵六', '66', '78', '99', '100', '303', '2023-07');

2、统计表

DROP TABLE IF EXISTS `score_stat`;
CREATE TABLE `score_stat`  (
  `chinese` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '语文',
  `math` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '数学',
  `English` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '英语',
  `physics` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '物理',
  `classroom` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '班级',
  `yearmonth` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '年月'
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '优秀成绩人数统计表' ROW_FORMAT = Dynamic;

dto层

@Data
public class ScoreStatDto {
    private String yearmonth;
    private String classroom;
    private String chinese;
    private String math;
    private String english;
    private String physics;
}

mapper层

@Mapper
public interface ScoreStatDtoMapper extends BaseMapper<ScoreStatDto> {
//4个集合插入
    int insertChinese(@Param("datas") List<ScoreStatDto> datas);
}

mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="xxx.xxx.ScoreStatDtoMapper">


    <insert id="insertChinese" parameterType="xxx.xxx.ScoreStatDto"
            useGeneratedKeys="true">
        INSERT INTO score_stat (yearmonth, classroom, chinese)
        values
        <foreach collection="datas" item="item" separator="," >
            (
            #{item.yearmonth,jdbcType=VARCHAR}, #{item.classroom,jdbcType=VARCHAR}, #{item.chinese,jdbcType=VARCHAR}
            )
        </foreach>
        ON DUPLICATE KEY UPDATE yearmonth = VALUES(yearmonth),classroom = VALUES(classroom),chinese = VALUES(chinese)
    </insert>

</mapper>

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

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

相关文章

区间预测 | MATLAB实现QRBiGRU双向门控循环单元分位数回归多输入单输出区间预测

区间预测 | MATLAB实现QRBiGRU双向门控循环单元分位数回归多输入单输出区间预测 目录 区间预测 | MATLAB实现QRBiGRU双向门控循环单元分位数回归多输入单输出区间预测效果一览基本介绍模型描述程序设计参考资料 效果一览 基本介绍 MATLAB实现QRBiGRU双向门控循环单元分位数回归…

EXCEL,如何比较2个表里的数据差异(使用数据透视表)

目录 1 问题: 需要比较如下2个表的内容差异 1.1 原始数据喝问题 1.2 提前总结 2 使用EXCEL公式方法 2.1 新增辅助列&#xff1a; 辅助index 2.2 具体公式 配合条件格式 使用 3 数据透视表方法 3.1 新增辅助列&#xff1a; 辅助index 3.2 需要先打开 数据透视表向导 …

基于CNN卷积神经网络的调制信号识别算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 1. 卷积神经网络&#xff08;CNN&#xff09; 2. 调制信号识别 3.实现过程 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2022A 3.部分核心程序 % 构建调制类型…

支付宝短视频平台创作分成激励项目

没想到支付宝也开通了中视频计划&#xff0c;这波羊毛算是蒿定了&#xff0c;最近啊&#xff0c;马爸爸火速上线了支付宝创作分成计划&#xff0c;明显就是抄的抖音中视频计划&#xff0c;目前还在内测阶段&#xff0c;补贴的力度非常大&#xff0c;错过的话就只能拍大腿了&…

Prometheus 的应用服务发现及黑河部署等

目录 promtool检查语法 部署Prometheus Server 检查语法是否规范 部署node-exporter 部署Consul 直接请求API进行服务注册 使用register命令注册服务&#xff08;建议使用&#xff09; 单个和多个注册&#xff0c;多个后面多加了s 在Prometheus上做consul的服务发现 部署…

windows安装linux

https://www.cnblogs.com/liuqingzheng/p/16271895.html 咱们安装linux系统是centos7 准备工作&#xff1a; 安装软件&#xff1a;vmware -------虚拟机 官网下载地址&#xff1a;下载 VMware Workstation Pro | CN 也可以从这里面下载 链接&#xff1a;https://pan.bai…

MySQL优化(面试)

文章目录 通信优化查询缓存语法解析及查询优化器查询优化器的策略 性能优化建议数据类型优化索引优化 优化关联查询优化limit分页对于varchar end mysql查询过程: 客户端向MySQL服务器发送一条查询请求服务器首先检查查询缓存&#xff0c;如果命中缓存&#xff0c;则立刻返回存…

行车遥控接线图

这个一般只有电工才会用。 主要是 【共线和总电】让人疑惑。 这图实际就是PLC的梯形图。 共电&#xff1a;接主电源。【它串联10A保险丝&#xff0c;再到继电器】 总电&#xff1a;它是所有继电器的公共端。【共电的继电器吸合&#xff0c;共电和总电就直通了。】共电的继电器…

Io进、线程——进程的基础

进程的基础 进程是计算机中最基本的执行单位&#xff0c;是程序在操作系统中的一次执行过程。每个进程都有自己的地址空间、数据栈、程序计数器等&#xff0c;相互之间独立运行&#xff0c;互不干扰。进程间的通信通过特定的机制来实现&#xff0c;进程的创建和撤销由操作系统…

详解Mybatis之动态sql问题

编译软件&#xff1a;IntelliJ IDEA 2019.2.4 x64 操作系统&#xff1a;win10 x64 位 家庭版 Maven版本&#xff1a;apache-maven-3.6.3 Mybatis版本&#xff1a;3.5.6 文章目录 一. 在sql映射文件中如何写注释&#xff1f;二. 什么是动态sql&#xff1f;三. 动态sql常用标签有…

Vue项目如何生成树形目录结构

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、有兴趣的可以关注一手。 前言 项目的目录结构清晰、可以帮助我们更快理顺项目的整体构成。在写文档之类的时候也比较方便。生成树形目录的方式有多种&#xff0c;我这里简单介绍其中一种较为简单的实现 过…

CSP 2021入门级 第一轮 题目讲解

A: a进栈&#xff0c;直接出栈&#xff1b;b进栈&#xff0c;直接出栈&#xff1b;c进栈&#xff0c;直接出栈&#xff1b;d进栈&#xff0c;直接出栈&#xff1b;e进栈&#xff0c;直接出栈。 B&#xff1a;全进栈后全出栈。 C&#xff1a;a和b先进栈&#xff0c;然后直接出…

【雕爷学编程】MicroPython动手做(09)——零基础学MaixPy之人脸识别2

自己打包kfpkg&#xff0c;试着整了好几次&#xff0c;都是无法烧录&#xff0c;只好不做第七步了&#xff0c;直接把前面获得的人脸识别模型烧录了 烧录完成后&#xff0c;打开IDE串口&#xff0c;确认开发板Maixpy固件的版本&#xff0c;好像是前期的稳定版本V0.4.0 第九步&a…

idea中创建请求基本操作

文章目录 说明效果创建GET请求没有参数带有参数带有环境变量带有动态参数 说明 首先通过###三个井号键来分开每个请求体&#xff0c;然后请求url和header参数是紧紧挨着的&#xff0c;请求参数不管是POST的body传参还是GET的parameter传参&#xff0c;都是要换行的&#xff0c;…

Java版本spring cloud + spring boot 电子招标采购系统源码

营造全面规范安全的电子招投标环境&#xff0c;促进招投标市场健康可持续发展 传统采购模式面临的挑战 一、立项管理 1、招标立项申请 功能点&#xff1a;招标类项目立项申请入口&#xff0c;用户可以保存为草稿&#xff0c;提交。 2、非招标立项申请 功能点&#xff1a;非招标…

《MySQL》第十二篇 数据类型

目录 一. 整数类型二. 浮点类型三. 日期和时间类型四. 字符串类型五. 枚举值类型六. 二进制类型七. 小结 MySQL 支持多种数据类型&#xff0c;学习好数据类型&#xff0c;才能更好的学习 MySQL 表的设计&#xff0c;让表的设计更加合理。 一. 整数类型 类型大小SIGNED(有符号)…

网红项目AutoGPT源码内幕及综合案例实战(三)

AutoGPT on LangChain PromptGenerator等源码解析 本节阅读AutoGPT 的prompt_generator.py源代码,其中定义了一个PromptGenerator类和一个get_prompt函数,用于生成一个提示词信息。PromptGenerator类提供了添加约束、命令、资源和性能评估等内容的方法,_generate_numbered_l…

effective c++ 条款2

条款2 常量(const)替换宏(#define)指针常量类成员常量 枚举(enum)替换宏(#define)模板函数(template inline)替换宏函数 尽量用const,enum,inline替换#define 总结就是&#xff1a; 常量(const)替换宏(#define) // uppercase names are usually for macros #define ASPECT_R…

HTML基础 第一课

文章目录 什么是HTMLHTML规范标签的种类开闭合标签整合标签标签中的属性 我的第一个HTML 什么是HTML Hyper Text Markup Language 超文本标记语言 超文本:表示页面上的一切要素&#xff0c;正如Java中的万物皆对象一样&#xff0c;在网页中包含 普通的文本样式 结构 视频 音频…

c++ 面试错题整理

在C中&#xff0c;下列哪个语句用于定义一个字符串变量&#xff1f;&#xff08;D&#xff09; A. string myString; B. char myString[]; C. String myString; D. char* myString; 关于为什么不是A&#xff0c;我猜测可能是因为string本质上是一个类。 C中的引用与指针有什么…