关于如何获取上周均值的实时数据思路,吾之解合君意否?

news2024/9/24 17:17:14

    📚 在前端界面图形化展示中,目前主流以报表形式,或者以曲线图形式展示其所需数据的数字动态变化效果居多。在数据量不大或者不需要模糊对比的情况下,我们以报表展示为主;而我们需要从肉眼宏观可见的监控数据变化,一眼能看出其数据变动问题的时候,曲线图的展示则是首选。

    📕 刚开始接手做项目大家应该都是从报表入手,因为这个较为简单,容易上手,逻辑上判断也并不复杂。但是曲线图上的开发考虑的因素就要更多一些:
⛳️(1)曲线数据值的取法怎样合适?
⛳️(2)曲线坐标轴当以多少分钟为时间间隔合适?
⛳️(3)数据库数据是否在所统计的时间点上有数值
⛳️(4)没有数值应当以何种方式进行补值

    ✂️这些并不是本人一开始就得知的,而是踩过坑并和前端同事对接后发现的问题。所谓不在其位不谋其政,一旦在岗工作有些坑该踩还得踩,该流的汗还得流,当然遇到很不合理的需求该battle还得battle~
    ✂️习惯上先说一段废话来引入主题:聊聊是如何获取上周均值的实时数据的(曲线图),主要根据曲线要考虑的因素展开思路剖析。

⚽️(一)数据取值

    🔭之所以在Java代码层面去做数据处理是因为我们在数据库层面sql语句不好处理复杂业务数据,或者没有能直接可用的函数供给我们使用,我们才会想到用代码实现逻辑更便捷一些。(这里提一嘴:有些sql不好处理的业务,交给Java Stream流会给你意想不到的简单惊喜哦!当然这里我没用到Stream流,因为我也是刚在这个项目中接触一丢丢,用得确实不6,以后当然会666 🎯O(∩_∩)O哈哈~🎯)

    🍻① 首先看一下我们的需求,拿上周七天的均值数据,那么取七天的数据是必然的。之前的文章有讲过易犯错点:“不要频繁滴访问数据库”,所以我们的做法是直接在数据库中取七天的原始数据在sql层面不做任何处理。这里也有一个“踩坑”环节,不是拿过去七天,而是拿上周七天。所以,我们还需有有一个判断环节,这个判断是要根据目前的日期往前推算:今天是周几,然后往前推算几天才能拿到上周每一天的数值。这个判断环节如果曲线图在项目中运用较多,可以将其封装成一个方法,不管是我们自己开发,还是后期同事进行维护代码会更轻松便捷。这里是借助Java DateUtil类自带方法,利用该方法判断今天是一周中的周几,然后进行逻辑判断,具体代码如下所示:

	  DateTime dateTime = DateUtil.date();
      Week week = DateUtil.dayOfWeekEnum(dateTime);
      Integer day = 0;

      switch (week){
          case MONDAY:
              day = 1;
              break;
          case TUESDAY:
              day = 2;
              break;
          case WEDNESDAY:
              day = 3;
              break;
          case THURSDAY:
              day = 4;
              break;
          case FRIDAY:
              day = 5;
              break;
          case SATURDAY:
              day = 6;
              break;
          case SUNDAY:
              day = 7;
              break;
          default:
              day = 0;
              break;
      }

    🍻② 确认完今日是当前周的第几天后,还要限定在哪个时间范围内,并将时间格式化成正确的传入参数,参考代码如下所示:

  //日期往前推day+6位开始时间,往前推day-1为截止时间
  LocalDate beginLocalDate = LocalDate.now().minusDays(day+6);
  LocalDate endLocalDate = LocalDate.now().minusDays(day-1);

  //时间格式化
  DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
  String beginFormat = dateTimeFormatter.format(beginLocalDate);
  String endFormat = dateTimeFormatter.format(endLocalDate);
  
  //在年月日的基础上加上时分秒
  String beginTime = beginFormat + " 00:00:00";
  String endTime = endFormat + " 00:00:00";
  
  //String转Date格式
  Date beginDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(beginTime);
  Date endDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(endTime);

    🍻③ 确认完开始时间和截止时间后,将beginDate 和 endDate 作为Mapper接口的入参查询数据即可完成数据取值的任务,参考代码如下:

List<?> lastWeekList= xxxMapper.selectXXX(beginDate, enDate);
//对应的Mapper接口省略,基本操作大家都会写。

    🍗由于项目用的是ClickHouse数据库,诸多写法跟MySQL不同,mysql的Group by是比较友好的,但是要用CK的Group By,小伙伴试试就知道里面的坑是超级多的,你要查询多个字段,那么那些字段都需要Group By,带查询条件的基本都是要这样做,用得痛苦不堪… …

    🍗提供用于ClickHouse中分组的友好函数(超好用),将时间按照五分钟间隔统计数据,如果大家也是用到了CK可以试试看,如果不是CK的话,mysql处理要好得多不用搞得这么复杂,ck时间函数参考以下:

formatDateTime(toStartOfInterval(loadtime, INTERVAL 5 minute ),'%T') as lastWeekLoadTime

⚽️(二)时间坐标轴的选定

    🍔原始数据取好之后,下一步开始处理数据,处理数据要想好值如何摆放的问题,就像水浒英雄排座次一样的道理,本来在哪的就在哪,摆放不能搞乱了,否则影响的是前端展示效果,造成数据扭曲。

    🍔坐标轴的选取,这里不能用数据库中查询的时间作为坐标轴。原因有二:
🍻(1)假设当前时间是没有数据的,那么在数据库中某一条或者某多条数据是缺失的,虽然后台程序不会报错,但是整体返回的值相对而言少了;
🍻(2)返回值一旦空缺,前端会以某个接口的时间点作为坐标轴画曲线,没有的值前端那边是无法简单进行判断的,他不会自动进行补值,而是会将值给顶出去,假设现在为16:00,但是数据库中的值为17:00,16:00~17:00中间是没有数值的,前端不会显示16:00,而是会直接那17:00之后的数据顶上。这样造成的后果就是,图形化展示出未来的时间,哦豁,有bug哦!

    🍧解决办法当然有,我们用自定义方法作为坐标轴,好处就是这条坐标轴是固定不变的,不会因为某个时间点上没有数据而不存在的问题,获取固定时间间隔的方法参考如下代码:

	/**
     * 获取固定时间间隔
     */
    public static List<String> getIntervalTimeList(String start, String end, int interval) {
        Date startDate = convertString2Date("HH:mm:ss", start);
        Date endDate = convertString2Date("HH:mm:ss", end);
        List<String> list = new ArrayList<>();
        while (startDate.getTime() <= endDate.getTime()) {
            list.add(convertDate2String("HH:mm:ss", startDate));
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startDate);
            calendar.add(Calendar.MINUTE, interval);
            if (calendar.getTime().getTime() > endDate.getTime()) {
                if (!startDate.equals(endDate)) {
                    list.add(convertDate2String("HH:mm:ss", endDate));
                }
                startDate = calendar.getTime();
            } else {
                startDate = calendar.getTime();
            }

        }
        return list;
    }

    🍧以上方法返回一个以interval为时间间隔,类型为String的timeList,我们传入参数也是要注意的,根据时间间隔来确认我们的start 和 end 具体为什么,参考代码如下:

//timeList长度为289,间隔五分钟288个数据, 间隔十分钟144个数据
List<String> timeList = DateUtils.getIntervalTimeList("00:00:00", "23:55:00", 5);

⚽️(三)结果的返回

    👑前两步的基础打好之后,后面的工作就好处理了,只需要将查询到的数据跟坐标轴进行匹配,匹配到之后整除7后进行返回,如果某个时间点没有值则可以返回null或者0,最终返回一个以interval为时间间隔完整的时间曲线。实例代码如下所示:

	List<?> list = new ArrayList();
	
	for (int i = 0; i < timeList.size(); i++) {
	   //业务逻辑匹配处理
	   Data data = new Data();
	
	   String lastWeekLoadTime = lastWeekList.get(i).getLastWeekLoadTime();
	   Integer num = 0;
	    
	   if (lastWeekLoadTime.equals(timeList.get(i))){
	       num = lastWeekList.get(i).getNum();
	   }
	
	   num /= 7;
	
	   String passTime = "2022-11-28 " + timeList.get(i);
	
	   data.setLoadtime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(passTime));
	   data.setNum(num);
	   list.add(data); 
	}
	
	return list;

⚽️(四)结语

🍰🍰🍰整个流程下来,主要是在代码层面对数据进行了一系列的处理。思路并不是一成不变的,需要时时刻刻撬动自己的脑筋才能把一个需求问题搞定。之前本人一直想在sql层面一次性把问题给解决了,左思右想最后发现自己根本不知道怎么动手合适。最终想到用传参到sql中和自定义方法解决问题,面临自己之前没接触过的数据库确实很多地方都是知识盲区,这个时候要多请教一下解决过相关业务的同事,多在网上寻求解决方案,希望自己的这点经历也能成为你们的“答案”🍭🍭🍭

🍆🍆🍆路过的小伙伴,如果本篇博文对你的学习或者工作有所帮助,可以点赞+收藏+关注一波呀~👊👊👊小编后续每过一段时间会整理出相关项目实例的博文,感谢您的支持哦!!!✈️✈️✈️
在这里插入图片描述

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

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

相关文章

volatile解决有序性和可见性问题

线程可见性问题分析 什么是可见性&#xff1f; 如果一个线程对一个共享变量进行了修改 而其他线程不能及时地读取修改后的值 所以在多线程情况下该共享变量就会存在可见性问题 package com.alipay.alibabademo.thread;import lombok.extern.slf4j.Slf4j;import java.util.co…

改进遗传算法在TSP问题中的应用(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

玩转Python图片处理(OpenCV)

OpenCV是一个基于BSD许可&#xff08;开源&#xff09;发行的跨平台计算机视觉库&#xff0c;可以运行在Linux、Windows、Android和Mac OS操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C 类构成&#xff0c;同时提供了Python、Ruby、MATLAB等语言的接口&#xff0c;…

Qt扫盲-QLabel使用总结

QLabel使用总结一、QLabel 显示内容二、注意事项1. 格式注意2. 不保留先前状态3. 格式对齐4. 伙伴焦点三、信号和槽函数使用1. 信号2. 槽函数总结&#xff1a;QLabel 其实就是一个用来只读显示的简易控件。适合数据量很小的内容显示。QLabel用于显示 文本或图像。 不提供用户交…

深度学习之目标检测通用技巧

深度学习之目标检测通用技巧深度学习之目标检测通用技巧深度学习之目标检测通用技巧 一 数据增强 1.离线增强 离线增强:对数据集进行处理&#xff0c;数据的数目会变成增强因子原数据集的数目 2.在线增强 对输入模型的batch的数据进行增强&#xff0c;如旋转、平移、翻折等…

今天给大家介绍一篇基于SSM的教材管理系統的设计与实现

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…

【Tensorflow学习三】神经网络搭建八股“六步法”编写手写数字识别训练模型

神经网络搭建八股“六步法”编写手写数字识别训练模型Sequential用法model.compile(optimizer优化器,loss损失函数,metrics["准确率"])model.fitmodel.summery六步法搭建鸢尾花分类网络class搭建具有非顺序网络结构MNIST数据集Fashion MNIST数据集用Tensorflow API:t…

java计算机毕业设计基于安卓Android的掌上酒店预订APP

项目介绍 网络的广泛应用给生活带来了十分的便利。所以把掌上酒店预订与现在网络相结合,利用java技术建设掌上酒店预订APP,实现掌上酒店预订的信息化。则对于进一步提高掌上酒店预订发展,丰富掌上酒店预订经验能起到不少的促进作用。 掌上酒店预订APP能够通过互联网得到广泛的…

基于风能转换系统的非线性优化跟踪控制(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清…

一、CDD在诊断开发中的作用

本专栏将由浅入深的展开诊断实际开发与测试的数据库编辑,包含大量实际开发过程中的步骤、使用技巧与少量对Autosar标准的解读。希望能对大家有所帮助,与大家共同成长,早日成为一名车载诊断、通信全栈工程师。 本文介绍CDD在诊断开发中的作用,欢迎各位朋友订阅、评论,可以提…

如何评价模型的好坏?

回归&#xff1a; MSE&#xff08;均方误差&#xff09;—— 判定方法&#xff1a;值越小越好&#xff08;真实值-预测值&#xff0c;平方之后求和平均&#xff09;RMSE&#xff08;均根方误差&#xff09;—— 判定方法&#xff1a;值越小越好&#xff08;MSE开根号&#xff…

Dijkstra最短路径算法

参考&#xff1a;(3条消息) Dijkstra算法图文详解_一叶执念的博客-CSDN博客_迪杰斯特拉算法 如图&#xff0c;假设图中共有n条路径&#xff08;如D-C-E&#xff09;&#xff0c;根据路径长度进行小到大排序。 1、起点到达某终点的距离是无穷符号&#xff0c;表示该起点还需要借…

27岁到来之际,我在阿里实现了年薪40W+的小目标

顺着大佬的思路&#xff0c;我分析了自己的实际水平和状况&#xff1a; 1、技术不精不成体系&#xff1a;技术能力浮于表面&#xff0c;对底层逻辑和架构不了解&#xff0c;也不知道如何系统化进行学习; 2、遇到职场瓶颈期&#xff1a;站在3年职场的分水岭上&#xff0c;没有…

Linux网络原理及编程(8)——第十八节 数据链路层

目录 1、MAC地址 2、MAC帧 3、MAC帧协议 4、MTU 5、ARP请求和应答 各位好&#xff0c;博主新建了个公众号《自学编程村》&#xff0c;拉到底部即可看到&#xff0c;有情趣可以关注看看哈哈&#xff0c;关注后还可以加博主wx呦~~~&#xff08;公众号拉到底部就能看到呦~~&a…

基于java+springmvc+mybatis+jsp+mysql的新冠肺炎疫苗接种管理系统

项目介绍 新冠疫苗接种管理系统&#xff0c;在网站首页可以查看首页&#xff0c;疫苗信息&#xff0c;疫苗资讯 &#xff0c;个人中心&#xff0c;后台管理&#xff0c;在线客服等内容&#xff0c;并进行详细操作。管理员登录进入系统可以查看首页&#xff0c;个人中心&#x…

vue自定义keepalive组件的问题解析

前一阵来了一个新的需求&#xff0c;要在vue项目中实现一个多开tab页面的功能&#xff0c;本来心想&#xff0c;这不简单嘛就是一个增加按钮重定向吗&#xff1f;&#xff08;当然如果这么简单我就不写这个文章了&#xff09;。很快写完&#xff0c;提交测试。测试大哥很快就提…

一份奇奇怪怪的地图设计书

地图设计书 地图设计是通过研究实验制定新编地图的内容、表现形式及其生产工艺程序的工作&#xff0c;是地图制图学各种活动的中心&#xff0c;贯穿整个地图制图过程。本设计选择了福建省龙岩市作为研究区域&#xff0c;并结合相应区域的土地利用类型、水系、道路等数据&#…

儿童剧本杀行业是好生意吗?剧本杀门店管理系统

红楼梦、西游记、水浒传、三国演义是中国四大名著&#xff0c;几乎每个中国人上到70岁老人&#xff0c;下到十岁小学生都知道&#xff0c;同时还有花木兰、包青天、八仙过海等故事也都耳濡目染&#xff0c;小说描述的淋漓尽致&#xff0c;影视剧老戏骨们将每个角色刻画的深入人…

spring-aop源码分析(3)完结_执行流程分析

本文详细介绍Spring AOP的执行阶段流程。 Cglib代理的代理拦截逻辑在DynamicAdvisedInterceptor中&#xff0c;JDK代理的拦截逻辑在JdkDynamicAopProxy中&#xff0c;本文将从这两个类入手分析Spring AOP的执行阶段流程。 DynamicAdvisedInterceptor private static class D…

Modbus数据采集方案

目录 目标 Modbus协议简介 配置界面以及实例 概述 modbus协议应该是工业行业应用最广泛的协议&#xff0c;由于其协议简单、通讯标准、扩展性强的特点&#xff0c;被各个行业大量的应用。作为通讯网关机来说&#xff0c;设计一个便捷易懂的配置方式显得尤其重要。本方案基于…