精华内容
下载资源
问答
  • Java计算同比环比
    千次阅读
    2020-12-08 09:59:34

    Java计算同比环比
    同比环比计算基本概念和计算公式
    同比率:本年数据比上一年数据增长或减少的比率
    同比率计算公式:rate = (本年数据 - 前一年数据) / 前一年数据
    实例:2020年10月游客数量为80W,2019年10月游客数量为100W,2018年10月游客数量为90W
    2020年同比率为:rate :(80 - 100)/100 * 100%= -20%
    2019年同比率为:rate :(100 - 900)/900 * 100%= +11%
    (“+” 为增长,“-”为降低)

    环比率:本月(季度)数据比上个月(季度)数据增长或减少的比率
    环比率计算公式:rate = (本月数据 - 上个月数据) / 上个月数据
    实例:2020年10月游客数量为100W,2020年9月游客数量为90W,2020年7月游客数量为80W
    2020年10月同比率为:rate :(100 - 90)/90 * 100%= +11%
    2019年10月同比率为:rate :(90- 80)/800 * 100%= +12.5%
    注:同比环比计算公式是相同的,但计算数据对应的时间是不同的

    代码实现逻辑
    通过Calendar等时间函数和HashMap,[ hashmap(key,value) key为时间,value为该时间对应的值]。将key和value一一对应的存入集合中,通过对key进行操作,再用key获取HashMap中相对应的value,套公式计算(重点在于对时间(key)的操作,通过key可直接获取value进行计算)

    详细逻辑步骤
    首先通过SQL语句获取数据库中相应的时间和该时间对应的数据,按时间分组排序

    SELECT
            DATAS.DATE AS NAME ,
            SUM( DATAS.VISITORSUM) AS VALUE,
            2 AS sfzj,
            '' AS bfb
            FROM
            (SELECT TOURIST.* ,CONCAT(YEAR,'年',QUARTER,'月') AS DATE
            FROM TOURISTFLOW TOURIST)DATAS
            GROUP BY DATAS.DATE
            ORDER BY DATAS.DATE
    

    接着设置时间范围,将最早的时间减去一年设为最小时间,最后的时间为最大时间,以此为范围即可保证覆盖所有数据

    // 设置时间范围
                // 获取最前的时间的第一个列表
                analyzeBean firstTimeSubway = analyzeByYear.get(0);
                String startTime = firstTimeSubway.getTime();
                // 获取最后时间的最后一个列表
                analyzeBean endTimeSubway = analyzeByYear.get(analyzeByYear.size() - 1);
                String endTime = endTimeSubway.getTime();
                // 时间格式转换
                SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月");
                Date parse = format.parse(startTime);
                Date parse1 = format.parse(endTime);
                Calendar c = Calendar.getInstance();
                c.setTime(parse);
                c.add(Calendar.YEAR, -1);
                Date y = c.getTime();
                // 获取最前的时间的前一年的时间作为查询范围
                String firstTime = format.format(y);
                analyzeRequestBean.setStartTime(firstTime);
                Calendar c1 = Calendar.getInstance();
                c1.setTime(parse1);
                Date y1 = c1.getTime();
                // 获取最后一年的时间作为查询范围
                String lastTime = format.format(y1);
                analyzeRequestBean.setStartTime(lastTime);
    

    在将所有数据的结果集存入HashMap中 hash(key,value) key为时间,value为数据值

    hashMap.put(time, analyzeByYear.get(i).getValue());
    

    最后通过for循环和CaleCndar函数和Date函数对时间(key)进行相应的操作,再通过时间(key)到HashMap中找对应的值进行计算

    for (int i = 0; i < analyzeByYear.size(); i++) {
                    AnalyzeBean analyzeBean = analyzeByYear.get(i);
                    if (i == 0) {
                    	// 是否增长("0:降低 1:增加 2:既不增长也不降低")
                        analyzeBean.setSfzj(2);
                        analyzeBean.setBfb(null);
                    } else {
                        SimpleDateFormat format2 = new SimpleDateFormat("yyyy年MM月");
                        // 当前数据
                        Date parse2 = format2.parse(analyzeBean.getTime());
                        Calendar c2 = Calendar.gaetInstance();
                        c2.setTime(parse2);
                        c2.add(Calendar.YEAR, 0);
                        Date t = c2.getTime();
                        String time = format2.format(t);
                        Integer value = hashMap.get(time);
                        // 往年数据
                        Date parse3 = format2.parse(time);
                        Calendar c3 = Calendar.getInstance();
                        c3.setTime(parse3);
                        c3.add(Calendar.YEAR, -1);
                        Date year = c3.getTime();
                        String time1 = format2.format(year);
                        Integer value1 = hashMap.get(time1);
                        if (null != value1 && null != value) {
                            if (value.equals(value1)) {
                                analyzeBean.setSfzj(2);
                                analyzeBean.setBfb(null);
                            } else {
                                if (value > value1) {
                                    analyzeBean.setSfzj(1);
                                } else {
                                    analyzeBean.setSfzj(0);
                                }
                                // 2个值减法 绝对值
                                int abs = Math.abs(value - value1);
                                float a = (float) (abs) / (float) value1 * 100;
                                analyzeBean.setBfb(a + "");
                            }
                        } else {
                            analyzeBean.setSfzj(2);
                            analyzeBean.setBfb(null);
                        }
                    }
                }
    

    同比实例代码:

    // 求同比
        @Override
        public Result getAnalyzeByYear(AnalyzeRequestBean analyzeRequestBean) {
            try {
                // 检查参数
                if (null == analyzeRequestBean) {
                    return ResultUtil.fail(ResultEnum.PARAMS_ERROR);
                }
    a
                List<AnalyzeBean> analyzeByYear
                        = InfoMapper.getAnalyzeByYear(analyzeRequestBean);
    
                if (analyzeByYear == null || analyzeByYear.size() == 0) {
                    return ResultUtil.ok(null);
                }
    
                // 设置时间范围
                // 获取最前的时间的第一个列表
                analyzeBean firstTimeSubway = analyzeByYear.get(0);
                String startTime = firstTimeSubway.getTime();
                // 获取最后时间的最后一个列表
                analyzeBean endTimeSubway = analyzeByYear.get(analyzeByYear.size() - 1);
                String endTime = endTimeSubway.getTime();
                // 时间格式转换
                SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月");
                Date parse = format.parse(startTime);
                Date parse1 = format.parse(endTime);
                Calendar c = Calendar.getInstance();
                c.setTime(parse);
                c.add(CaleCndar.YEAR, -1);
                Date y = c.getTime();
                // 获取最前的时间的前一年的时间作为查询范围
                String firstTime = format.format(y);
                analyzeRequestBean.setStartTime(firstTime);
                Calendar c1 = Calendar.getInstance();
                c1.setTime(parse1);
                Date y1 = c1.getTime();
                // 获取最后一年的时间作为查询范围
                String lastTime = format.format(y1);
                analyzeRequestBean.setStartTime(lastTime);
                // 把大范围的结果集都放入hashMap中
                HashMap<String, Integer> hashMap = new HashMap<>();
                for (int i = 0; i < analyzeByYear.size(); i++) {
                    analyzeBean analyzeBean = analyzeByYear.get(i);
                    SimpleDateFormat format1 = new SimpleDateFormat("yyyy年MM月");
                    Date parse2 = format1.parse(analyzeBean.getTime());
                    Calendar c2 = Calendar.getInstance();
                    c2.setTime(parse2);
                    c2.add(Calendar.YEAR, 0);
                    Date t = c2.getTime();
                    String time = format1.format(t);
                    hashMap.put(time, analyzeByYear.get(i).getValue());
                }
    
                for (int i = 0; i < analyzeByYear.size(); i++) {
                    AnalyzeBean analyzeBean = analyzeByYear.get(i);
                    if (i == 0) {
                    	// 是否增长("0:降低 1:增加 2:既不增长也不降低")
                        analyzeBean.setSfzj(2);
                        analyzeBean.setBfb(null);
                    } else {
                        SimpleDateFormat format2 = new SimpleDateFormat("yyyy年MM月");
                        // 当前数据
                        Date parse2 = format2.parse(analyzeBean.getTime());
                        Calendar c2 = Calendar.gaetInstance();
                        c2.setTime(parse2);
                        c2.add(Calendar.YEAR, 0);
                        Date t = c2.getTime();
                        String time = format2.format(t);
                        Integer value = hashMap.get(time);
                        // 往年数据
                        Date parse3 = format2.parse(time);
                        Calendar c3 = Calendar.getInstance();
                        c3.setTime(parse3);
                        c3.add(Calendar.YEAR, -1);
                        Date year = c3.getTime();
                        String time1 = format2.format(year);
                        Integer value1 = hashMap.get(time1);
                        if (null != value1 && null != value) {
                            if (value.equals(value1)) {
                                analyzeBean.setSfzj(2);
                                analyzeBean.setBfb(null);
                            } else {
                                if (value > value1) {
                                    analyzeBean.setSfzj(1);
                                } else {
                                    analyzeBean.setSfzj(0);
                                }
                                // 2个值减法 绝对值
                                int abs = Math.abs(value - value1);
                                float a = (float) (abs) / (float) value1 * 100;
                                analyzeBean.setBfb(a + "");
                            }
                        } else {
                            analyzeBean.setSfzj(2);
                            analyzeBean.setBfb(null);
                        }
                    }
                }
                return ResultUtil.ok(analyzeByYear);
            } catch (ParseException ex) {
                ex.printStackTrace();
            }
            return ResultUtil.ok(null);
    

    环比类似,只是把c.add(Calendar.YEAR, 0);换成c.add(Calendar.MONTH, 0)
    实现逻辑其实不难,只是我写复杂了,如有更好的方法欢迎留言交流讨论## Java计算同比环比

    更多相关内容
  • 是指在相邻时段中的某一相同时间点进行比较如图片所示,13年和14年是相邻时段,13年3月和14年3月是这两个相邻时段的同一个时间点,都是3月,这两个时段进行数据对比,就是同比;所以,14年3月的订单量是80,13年3月...

    参考:https://jingyan.baidu.com/article/f96699bba855cf894e3c1b04.html

    同比,是指在相邻时段中的某一相同时间点进行比较

    如图片所示,13年和14年是相邻时段,13年3月和14年3月是这两个相邻时段的同一个时间点,都是3月,这两个时段进行数据对比,就是同比;

    所以,14年3月的订单量是80,13年3月订单量是70,则我们可以这样写:14年3月订单量同比13年增长14.3%。

    7b11af79fbc965496789612887098c38.png

    环比,则相对更简单,就是相邻时间段的对比,不象同比那样,是在相邻时间段内部的某个相同时间点的对比;

    如图所示,14年4月和14年3月是相邻时间段,这两个时间段的数据都比,就是环比;

    当然我们也可以把13年全年的数据和14年全年的数据进行对比,这个数据也可以看成是环比。

    e917d2635e270021c029b30b4a479303.png

    同比一般情况下是今年第n月与去年第n月比。同比发展速度主要是为了消除季节变动的影响,用以说明本期发展水平与去年同期发展水平对比而达到的相对发展速度。如,本期2月比去年2月,本期6月比去年6月等。

    同比发展速度的公式:同比发展速度=本期发展水平/去年同期水平×100%;

    同比增长速度=(本期发展水平-去年同期水平)/去年同期水平×100%;

    在实际工作中,经常使用这个指标,如某年、某季、某月与上年同期对比计算的发展速度,就是同比发展速度。

    环比,表示连续2个单位周期(比如连续两月)内的量的变化比。

    环比增长率=(本期数-上期数)/上期数×100%。 反映本期比上期增长了多少;环比发展速度,一般是指报告期水平与前一时期水平之比,表明现象逐期的发展速度。

    同比增长率=(本期数-同期数)/|同期数|×100%

    b739ec46bb5c46d9c0aa4ce35ba1ea56.png

    关于找一找教程网

    本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。

    本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。

    [数据相关概念同比,环比]http://www.zyiz.net/tech/detail-131757.html

    展开全文
  • java计算同比环比

    2021-12-02 10:13:04
    @java计算同比环比 同比环比的概念 同比环比的区别:同比是不连续的两期数据做对比;环比是两期连续数据做对比。计算方式:环比增长率=(本期数-上期数)/上期数×100%;同比增长率=(本期数-同期数)÷同期数×...

    @java计算同比和环比

    同比和环比的概念

    同比和环比的区别:
    同比是不连续的两期数据做对比;环比是两期连续数据做对比。计算方式:环比增长率=(本期数-上期数)/上期数×100%;同比增长率=(本期数-同期数)÷同期数×100%;同比更加侧重反映长期的大趋势,环比会突出显示数据的短期趋势。

    计算基准

    根据计算的基准不同,可分为周环比,月环比,日环比,周同比,月同比,日同比等,代入到上面的公式,以月为例,
    月环比增长率=(本月数-上月数)/上月数
    月同比增长率=(本月数-去年本月数)/ 去年本月数

    java 通用方法

    因此需要根据基准单位的不同去向前推对应单位的日期。
    本方法依次传入现在的日期,前推的数量,前推的单位,执行后将计算的数据以Data类型返回

    /**
         * 获得指定日期之前一段时期的日期。例如某日期之前3天的日期等。
         *
         * @param origDate
         *            基准日期
         * @param amount
         *            时间数量
         * @param timeUnit
         *            时间单位,如年、月、日等。用Calendar中的常量代表,
         *            Calendar.YEAR-年
         *            Calendar.MONTH-月
         *            Calendar.DATE-日
         * @return {@link Date}
         */
        public static Date dateBefore(Date origDate, int amount, int timeUnit) {
            Calendar calendar = Calendar.getInstance();
            calendar.add(timeUnit, -amount);
            return calendar.getTime();
        }
    

    可能会有向后推算日期的场景,所以在此将负号变成正,即完成了对此方法的更改。

    /**
         * 获得指定日期之后一段时期的日期。例如某日期之后3天的日期等。
         *
         * @param origDate
         *            基准日期
         * @param amount
         *            时间数量
         * @param timeUnit
         *            时间单位,如年、月、日等。用Calendar中的常量代表,
         *            Calendar.YEAR-年
         *            Calendar.MONTH-月
         *            Calendar.DATE-日
         * @return {@link Date}
         */
        public static Date dateAfter(Date origDate, int amount, int timeUnit) {
            Calendar calendar = Calendar.getInstance();
            calendar.add(timeUnit, amount);
            return calendar.getTime();
        }
    

    代码验证实例。

    import java.text.DateFormat;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.Locale;
    
    public class DataCount {
        /**
         * 获得指定日期之前一段时期的日期。例如某日期之前3天的日期等。
         *
         * @param origDate
         *            基准日期
         * @param amount
         *            时间数量
         * @param timeUnit
         *            时间单位,如年、月、日等。用Calendar中的常量代表,
         *            Calendar.YEAR-年
         *            Calendar.MONTH-月
         *            Calendar.DATE-日
         * @return {@link Date}
         */
        public static Date dateBefore(Date origDate, int amount, int timeUnit) {
            Calendar calendar = Calendar.getInstance();
            calendar.add(timeUnit, -amount);
            return calendar.getTime();
        }
    
        /**
         * 获得指定日期之后一段时期的日期。例如某日期之后3天的日期等。
         *
         * @param origDate
         *            基准日期
         * @param amount
         *            时间数量
         * @param timeUnit
         *            时间单位,如年、月、日等。用Calendar中的常量代表,
         *            Calendar.YEAR-年
         *            Calendar.MONTH-月
         *            Calendar.DATE-日
         * @return {@link Date}
         */
        public static Date dateAfter(Date origDate, int amount, int timeUnit) {
            Calendar calendar = Calendar.getInstance();
            calendar.add(timeUnit, amount);
            return calendar.getTime();
        }
    
        public static void main(String[] args) {
            DateFormat df1 = DateFormat.getDateInstance();//日期格式,精确到日
            System.out.println("计算前置日期前");
            Date date1 = new Date();
            DateFormat YEAR_FORMAT = new SimpleDateFormat("yyyy");
            DateFormat MONTH_FORMAT = new SimpleDateFormat("MM");
            DateFormat Day_FORMAT = new SimpleDateFormat("dd");
            System.out.println(YEAR_FORMAT.format(date1));
            System.out.println(MONTH_FORMAT.format(date1));
            System.out.println(Day_FORMAT.format(date1));
            System.out.println(df1.format(date1));
    
            System.out.println(date1);
    
            System.out.println("计算前置日期后");
            Date date = dateBefore(date1, 1, Calendar.DATE);
            System.out.println(YEAR_FORMAT.format(date));
            System.out.println(MONTH_FORMAT.format(date));
            System.out.println(Day_FORMAT.format(date));
            System.out.println(date);
            System.out.println(df1.format(date));
    
    
    
            System.out.println("计算后置日期后");
            Date dateAfter = dateAfter(date1, 1, Calendar.DATE);
            System.out.println(YEAR_FORMAT.format(dateAfter));
            System.out.println(MONTH_FORMAT.format(dateAfter));
            System.out.println(Day_FORMAT.format(dateAfter));
            System.out.println(dateAfter);
            System.out.println(df1.format(dateAfter));
        }
    }
    
    

    输出结果截图

    在这里插入图片描述

    展开全文
  • Java环比计算相关逻辑相关概念背景实现思路具体代码SQL实现方式[Mysql]按月进行分组同比 2022年/2020年各月数据同比按月进行分组同比 各月数据环比 相关概念 「同比」 与历史「同时期]比较,例如2011年3月份与...

    相关概念

    「同比」
    与历史「同时期]比较,例如2011年3月份与2010年3月份相比,叫「同比」。
    同比是“同期”的比较,中间有可能跨了若干个统计周期,或者没有跨越一个统计周期。跨越了若干个统计周期的同比与环比不一样,而一个统计周期也没有跨越的同比实际上与环比是一样的
    同比是“同期”的比较,中间有可能跨了若干个统计周期,或者没有跨越一个统计周期。跨越了若干个统计周期的同比与环比不一样,而一个统计周期也没有跨越的同比实际上与环比是一样的
    「环比」
    与「上一个」统计周期比较,例如2011年4月份与2011年3月份相比较,称为「环比」。
    本期环比增长(下降)率(%) = (本期价格/上期价格 — 1 )× 100%
    本期同比增长(下降)率(%) = (本期价格/上年同期价格 —1) × 100%

    背景

    项目中使用了不同种数据库,为了减少工作量,不在数据库层进行同环比计算(需要查看不同数据库函数语法).所以决定在代码层面实现

    实现思路

    使用标记,或者缓冲避免多次循环数据
    环比
    1.降序排序
    2.环比计算
    循环结果集(不连续时间区间)
    取标记位数据(标记位默认为1)使用下标
    根据日期判断是不是相邻区间
    如果是->直接计算,标志位➕1
    如果不是->结果为0,标志位不变
    时间复杂度O(n)

    同比
    1.升序排序
    2.同比计算(不连续时间区间)
    设置缓冲时间区间数据List<Map(以年,不同月为key)>
    与缓冲区间判断年是否是相邻年(默认比较相邻年)
    如果是->取对应的月数据
    取到数据,计算
    取不到,结果为0
    如果不是->本年度所有月同比为0
    时间复杂度为O(n)

    具体代码

    方法无法直接使用,需要结合自己逻辑改进

    
    private List<Map<String, Object>> momYoyData(List<Map<String, Object>> obj,QueryDataSetBo bo){
            Map<String, Object> momCOUNTSet = bo.getMomCOUNTSet();
            //时间字段
            String fieldName = (String)momCOUNTSet.get("fieldName");
            String timeFieldKey=null;
            //时间字段类型【年,月,日,周,季,半年度】
            int type=(int)momCOUNTSet.get("type");
            switch (type){
                case 1:
                    timeFieldKey="date_format(column, '%Y')".replace("column",fieldName);
                    break;
                case 2:
                    timeFieldKey="date_format(column, '%Y-%m')".replace("column",fieldName);
                    break;
                case 3:
                    timeFieldKey="date_format(column, '%Y-%m-%d')".replace("column",fieldName);
                    break;
                case 4:
                    timeFieldKey="date_format(column,'%Y-%u')".replace("column",fieldName);
                    break;
                case 5:
                    timeFieldKey="concat(date_format(column, '%Y'),'-',FLOOR((date_format(column, '%m')+2)/3))".replace("column",fieldName);
                    break;
                case 6:
                    timeFieldKey="concat(date_format(column, '%Y'),'-',CEIL((date_format(column, '%m'))/6))".replace("column",fieldName);
                    break;
                default:
                    break;
            }
    
            //数据字段
            List<Map<String, Object>> dataFieldName = (List<Map<String, Object>>)momCOUNTSet.get("dataFieldName");
            ArrayList<String> yoyfieldList = new ArrayList<>(); //同比字段list
            ArrayList<String> momfieldList = new ArrayList<>(); //环比字段list
            for (Map<String, Object> stringObjectMap : dataFieldName) {
    
                String value = String.valueOf(stringObjectMap.get("value"));
                String compute = String.valueOf(stringObjectMap.get("compute"));
                String dataFieldkey=value+"_"+compute;
    
                if ((int)stringObjectMap.get("momYoyType")==1){
                    //同比
                    yoyfieldList.add(dataFieldkey);
                }else if ((int)stringObjectMap.get("momYoyType")==2){
                    //环比
                    momfieldList.add(dataFieldkey);
                }
            }
            //同比
            //升序
            List<Map<String, Object>> yoyDataList =new ArrayList<>();
            List<Map<String, Object>> maps =new ArrayList<>(obj);
            String finalTimeFieldKey=timeFieldKey;
            Collections.sort(maps, new Comparator<Map<String, Object>>() {
                    @Override
                    public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                        String o11 = (String)o1.get(finalTimeFieldKey);
                        String o22 = (String)o2.get(finalTimeFieldKey);
                        return o11.compareTo(o22);
                    }
                });
            if (yoyfieldList!=null&&yoyfieldList.size()>0){
                Map<String, Object> bufferMap = new HashMap<>();
                for (int i = 0; i < maps.size(); i++) {
                    Map<String, Object> newMap=new HashMap<>();
                    Map<String, Object> map=maps.get(i);
                    newMap.putAll(map);
                    String time = (String) map.get(finalTimeFieldKey);
                    String[] split = time.split("-");
                    String year=split[0];
                    String time2=split[1];
                    String lastYear = getLastYear(year);
                    if (bufferMap.containsKey(lastYear)&&bufferMap.get(lastYear)!=null){
                        HashMap<String, Object > dataMap = (HashMap<String, Object>)bufferMap.get(lastYear);
                        for (String yoyfield : yoyfieldList) {
                            if (dataMap.containsKey(time2)||dataMap.get(time2)!=null){
                                Map<String, Object> databufferMap = (Map<String, Object>)dataMap.get(time2);
                                if (map.containsKey(yoyfield)&&map.get(yoyfield)!=null&&databufferMap.containsKey(yoyfield)&&databufferMap.get(yoyfield)!=null){
                                    BigDecimal p = new BigDecimal((Double) map.get(yoyfield));
                                    BigDecimal q = new BigDecimal((Double) databufferMap.get(yoyfield));
                                    BigDecimal rate = new BigDecimal(0.000000);
                                    rate=(p).divide(q,3, RoundingMode.HALF_UP);
                                    newMap.put(yoyfield+"_"+"yoy",Double.valueOf(rate.toString()));
                                }else {
                                    newMap.put(yoyfield+"_"+"yoy",0);
                                }
                            }else {
                                newMap.put(yoyfield+"_"+"yoy",0);
                            }
                        }
    
                    }else {
                        for (String yoyfield : yoyfieldList) {
                            newMap.put(yoyfield+"_"+"yoy",0);
                        }
                    }
    
                    yoyDataList.add(newMap);
                    //操作缓冲MaP
                    if (i==0){
                        Map<String, Object> dataMap=new HashMap<>();
                        dataMap.put(time2,map);
                        bufferMap.put(year,dataMap);
                    }else{
                        if (bufferMap.containsKey(year)&&bufferMap.get(year)!=null){
                            HashMap<String, Object > dataMap = (HashMap<String, Object>)bufferMap.get(year);
                            dataMap.put(time2,map);
                            bufferMap.put(year,dataMap);
                        }else {
                            Map<String, Object> dataMap=new HashMap<>();
                            dataMap.put(time2,map);
                            bufferMap.put(year,dataMap);
                        }
                    }
                }
            }
    
    
                //环比
                //升序
                List<Map<String, Object>> maps2 =new ArrayList<>(obj);
                Collections.sort(maps2, new Comparator<Map<String, Object>>() {
                    @Override
                    public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                        String o11 = (String)o1.get(finalTimeFieldKey);
                        String o22 = (String)o2.get(finalTimeFieldKey);
                        return o22.compareTo(o11);
                    }
                });
                List<Map<String, Object>> momDataList =new ArrayList<>();
                if (momfieldList!=null&&momfieldList.size()>0){
                    for (int i = 0; i < maps2.size(); i++) {
                        Map<String, Object> map=maps2.get(i);
    
                        Map<String, Object> newMap=new HashMap<>();
                        newMap.putAll(map);
                        if (i==maps2.size()-1){
                            for (String momfield : momfieldList) {
                                newMap.put(momfield+"_"+"mom",0);
                            }
                        }else {
                            Map<String, Object> nextMap=maps2.get(i+1);
                            String time = (String) map.get(finalTimeFieldKey);
                            String nextTime = (String) nextMap.get(finalTimeFieldKey);
    
                            if (isContinuous(time,nextTime,type)) {
                                for (String momfield : momfieldList) {
                                    if (map.containsKey(momfield)&&map.get(momfield)!=null&&nextMap.containsKey(momfield)&&nextMap.get(momfield)!=null){
                                        BigDecimal p = new BigDecimal((Double) map.get(momfield));
                                        BigDecimal q = new BigDecimal((Double) nextMap.get(momfield));
                                        BigDecimal rate = new BigDecimal(0.000000);
                                        rate=(p).divide(q,3, RoundingMode.HALF_UP);
                                        newMap.put(momfield+"_"+"mom",Double.valueOf(rate.toString()));
                                    }else {
                                        newMap.put(momfield+"_"+"mom",0);
                                    }
                                }
                            }else {
                                for (String momfield : momfieldList) {
                                    newMap.put(momfield+"_"+"mom",0);
                                }
                            }
                        }
                        momDataList.add(newMap);
                    }
                }
    
    
            obj.addAll(momDataList);
            obj.addAll(yoyDataList);
            List<Map<String, Object>> merge = merge(obj, timeFieldKey);
            Collections.sort(merge, new Comparator<Map<String, Object>>() {
                @Override
                public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                    String o11 = (String)o1.get(finalTimeFieldKey);
                    String o22 = (String)o2.get(finalTimeFieldKey);
                    return o11.compareTo(o22);
                }
            });
            return merge;
        }
    
        private String getLastYear(String year){
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy");
            try {
                Date parse = simpleDateFormat.parse(year);
                Calendar cal=Calendar.getInstance();
                cal.setTime(parse);
                cal.add(Calendar.YEAR,-1);
                Date time = cal.getTime();
                return simpleDateFormat.format(time);
            } catch (ParseException e) {
                return null;
            }
        }
    
        private String getlastDay(String daystr){
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            try {
                Date parse = simpleDateFormat.parse(daystr);
                Calendar c = Calendar.getInstance();
                c.setTime(parse);
                int day=c.get(Calendar.DATE);
                c.set(Calendar.DATE,day-1);
                return new SimpleDateFormat("yyyy-MM-dd").format(c.getTime());
    
            } catch (Exception e) {
                return null;
            }
        }
    
        private boolean isContinuous(String time,String nextTime,Integer type){
    
            boolean isContinuous=false;
    
            String[] split = time.split("-");
            String yearTime=split[0];
            String timeTime=split[1];
            String[] split2 = nextTime.split("-");
            String yearNextTime=split2[0];
            String timeNextTime=split2[1];
    
            switch (type){
                case 1:
                    if (yearNextTime.equals(getLastYear(yearTime))){
                        isContinuous=true;
                    }
                    break;
                case 2:
                    if (yearTime.equals(yearNextTime)){
                        if (Integer.valueOf(timeTime)-Integer.valueOf(timeNextTime)==1){
                            isContinuous=true;
                        }
                    }if (yearNextTime.equals(getLastYear(yearTime))){
                        if (Integer.valueOf(timeTime)==1&&Integer.valueOf(timeNextTime)==12){
                            isContinuous=true;
                        }
                    }
                    break;
                case 3:
                    if (getlastDay(time).equals(nextTime)){
                        isContinuous=true;
                    }
                    break;
                case 4:
                    if (yearTime.equals(yearNextTime)){
                            if (Integer.valueOf(timeTime)-Integer.valueOf(timeNextTime)==1){
                                isContinuous=true;
                            }
                        }if (yearNextTime.equals(getLastYear(yearTime))){
    
                            if ((Integer.valueOf(timeTime)==1&&Integer.valueOf(timeNextTime)!=0&&(Integer.valueOf(timeNextTime)==52||Integer.valueOf(timeNextTime)==53))
                                ||(Integer.valueOf(timeTime)==0&&(Integer.valueOf(timeNextTime)==52||Integer.valueOf(timeNextTime)==53))
                            ){
                                isContinuous=true;
                            }
                        }
                    break;
                case 5:
                    if (yearTime.equals(yearNextTime)){
                            if (Integer.valueOf(timeTime)-Integer.valueOf(timeNextTime)==1){
                                isContinuous=true;
                            }
                        }if (yearNextTime.equals(getLastYear(yearTime))){
                        if (Integer.valueOf(timeTime)==1&&Integer.valueOf(timeNextTime)==4){
                            isContinuous=true;
                        }
                    }
                    break;
                case 6:
                    if (yearTime.equals(yearNextTime)){
                            if (Integer.valueOf(timeTime)-Integer.valueOf(timeNextTime)==1){
                                isContinuous=true;
                            }
                        }if (yearNextTime.equals(getLastYear(yearTime))){
                        if (Integer.valueOf(timeTime)==1&&Integer.valueOf(timeNextTime)==2){
                            isContinuous=true;
                        }
                    }
                    break;
                default:
                    break;
            }
            return isContinuous;
        }
    
        public static List<Map<String, Object>> merge(List<Map<String, Object>> m1,String mergeKey){
            Set<String> set = new HashSet<>();
            System.out.println("m1的数据格式是:"+m1);
            return m1.stream()
                    .filter(map->map.get(mergeKey)!=null)
                    .collect(Collectors.groupingBy(o->{
                        //暂存所有key
                        set.addAll(o.keySet());
                        //按mergeKey分组
                        return o.get(mergeKey).toString();
                    }))
                    .entrySet().stream().map(o->{
                        //合并
                        Map<String, Object> map = o.getValue().stream().flatMap(m->{
                            return m.entrySet().stream();
                        }).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a,b)->b));
                        //为没有的key赋值0
                        set.stream().forEach(k->{
                            if(!map.containsKey(k)) map.put(k, 0);
                        });
                        return map;
                    }).collect(Collectors.toList());
    
        }
    

    SQL实现方式[Mysql]

    在这里插入图片描述

    -- 年【普通年】/【闰年】
    SELECT
    	date_format(time1, '%Y'),
    	round( sum( time1_data ) / 1, 1 ) 
    FROM
    	time_test 
    	WHERE time1  is not null
    GROUP BY
    date_format(time1, '%Y')
    
    
    -- 月【普通年】/【闰年】
    SELECT
    	date_format(time1, '%Y-%m'),
    	round( sum( time1_data ) / 1, 1 ) 
    FROM
    	time_test 
    	WHERE time1  is not null
    GROUP BY
    date_format(time1, '%Y-%m')
    
    
    -- 日【普通年】/【闰年】
    SELECT
    	date_format(time1, '%Y-%m-%d'),
    	round( sum( time1_data ) / 1, 1 ) 
    FROM
    	time_test 
    	WHERE time1  is not null
    GROUP BY
    date_format(time1, '%Y-%m-%d')
    
    
    
    -- 季度 【普通年】/【闰年】 
    SELECT
    	concat(date_format(time1, '%Y'),'--',FLOOR((date_format(time1, '%m')+2)/3)),
    	round( sum( time1_data ) / 1, 1 ) 
    FROM
    	time_test
    WHERE time1  is not null	
    GROUP BY
    concat(date_format(time1, '%Y'),'--',FLOOR((date_format(time1, '%m')+2)/3))
    
    
    
    -- 半年度 【普通年】/【闰年】
    SELECT
    	concat(date_format(time1, '%Y'),'--',CEIL((date_format(time1, '%m'))/6)),
    	round( sum( time1_data ) / 1, 1 ) 
    FROM
    	time_test
    WHERE time1  is not null	
    GROUP BY
    concat(date_format(time1, '%Y'),'--',CEIL((date_format(time1, '%m'))/6))
    
    
    -- 周 【普通年】/【闰年】
    
    SELECT
    	DATE_FORMAT(time1,'%Y%u'),
    	round( sum( time1_data ) / 1, 1 )
    FROM
    	time_test 
    WHERE time1  is not null
    GROUP BY
    DATE_FORMAT(time1,'%Y%u')
    

    按月进行分组同比 2022年/2020年各月数据同比

    -- 按月进行分组同比 2022/2020年各月数据同比
    SELECT 
    a1.time,
    a1.`month`,
    ifnull(round(a1.`DATA`/b1.`DATA`,2),0) AS 同比
    FROM 
    (
    -- 2022年各月数据
    SELECT 
    time,
    `DATA`,
    SUBSTRING_INDEX(time,"-",-1) 	AS `month`
    from (
    SELECT
    	date_format(time1, '%Y-%m') AS time,
    	round( sum( time1_data ) / 1, 1 )	AS `DATA`
    FROM
    	time_test 
    	WHERE time1  is not null 
    	AND
    	date_format(time1, '%Y')='2022'
    GROUP BY
    date_format(time1, '%Y-%m')
    ) a
    ) a1
    LEFT JOIN
    (
    -- 2020年各月数据
    SELECT 
    time,
    `DATA`,
    SUBSTRING_INDEX(time,"-",-1) 	AS `month`
    from (
    SELECT
    	date_format(time1, '%Y-%m') AS time,
    	round( sum( time1_data ) / 1, 1 )	AS `DATA`
    FROM
    	time_test 
    	WHERE time1  is not null 
    	AND
    	date_format(time1, '%Y')='2020'
    	-- 非连续性数据
    	 AND date_format(time1, '%Y-%m') !='2020-05'
    GROUP BY
    date_format(time1, '%Y-%m')
    ) b
    ) b1
    ON a1.`month`=b1.`month`
    

    按月进行分组同比 各月数据环比

    SELECT 
    a1.time,
    b1.time,
    ifnull(round(a1.`DATA`/b1.`DATA`,2),0) AS 环比,
    a1.`DATA`,
    b1.`DATA`
    FROM 
    (
    SELECT 
    time,
    `DATA`,
    SUBSTRING_INDEX(time,"-",1) 	AS `year`,
    SUBSTRING_INDEX(time,"-",-1) 	AS `month`
    from (
    SELECT
    	date_format(time1, '%Y-%m') AS time,
    	round( sum( time1_data ) / 1, 1 )	AS `DATA`
    FROM
    	time_test 
    	WHERE time1  is not null 
    GROUP BY
    date_format(time1, '%Y-%m')
    ) a
    ) a1
    LEFT JOIN
    (
    SELECT 
    time,
    `DATA`,
    SUBSTRING_INDEX(time,"-",1) 	AS `year`,
    SUBSTRING_INDEX(time,"-",-1) 	AS `month`
    from (
    SELECT
    	date_format(time1, '%Y-%m') AS time,
    	round( sum( time1_data ) / 1, 1 )	AS `DATA`
    FROM
    	time_test 
    	WHERE time1  is not null 
    GROUP BY
    date_format(time1, '%Y-%m')
    ) b
    ) b1
    ON a1.`year`=b1.`year` AND a1.`month`=b1.`month`+1
    ORDER BY a1.time desc
    
    展开全文
  • 数据分析:同比-环比

    2021-11-24 22:57:37
    文章目录数据分析:同比-环比同比-环比同比环比日期获取:上月-本季-本年类设计CaseConsts:时间类型常量(本月、本季、本年)DateListBean:时间Bean方法设计getDateList:根据时间类型获取时间checkStartDate:...
  • java 柱形图 饼图 折线图 JFreeChart,里面包含与JFreeChart有关的所有jar包,还有我自己写的例子,通俗易懂!
  • 公众号后台回复“图书“,了解更多号主新书内容 作者:NK冬至 来源:首席数据科学家“今天和大家聊聊同比环比等指标的详细内容。”好久没有分享关于数据分析指标相关的内容了。...
  • Hive之同比环比的计算

    2022-02-14 00:33:06
    关注公众号:大数据技术派,回复: 资料,领取1024G资料。目录同比环比的计算测试数据销售量的月年占比同比环比同比环比的计算测试数据1,2020-04-20,420 2,2020-04-0...
  • 同比:某个周期的时段与上一个周期的相同时段比较,如今年的6月比去年的6月,本周的周一比上周的周一等等。环比:某个时段与其上一个时长相等的时段做比较,比如本周环比上周等等。1)环比增长率=(本期数-上期数)/...
  • 环比数据是指与同年的上一期相比的数据。如果做的是周数据比较,环比就是本周数据上周的数据;如果做的是月数据比较,环比就是本月数据上月的数据;如果做的是季数据比较,环比就是本季数据上季的数据。对于...
  • java 计算同比增长工具类

    千次阅读 2019-08-06 17:50:58
    java计算同比增长率的工具类 为了数据的严谨性,统一装换为BigDecimal,话不多说,看代码。 欢迎大家加群 进行讨论 qq群:714398799 package com.pig4cloud.pigx.admin.api.util; import java.math.BigDecimal; ...
  • 展开全部同比增长率=(本期数-同期数)÷同期数×100%同比表示第n月与第62616964757a686964616fe78988e69d8331333431373932n月比(n≤12),说明本期发展水平与同期发展水平对比达到的相对发展速度。举例:去年3月的...
  • 1.学生表数据 2.将学生按照性别区分 我们一般的写法就是使用group by进行分组。 select t.ssex, count(t.sname) from STUDENT t group by t.ssex; 如果我们需要求男生的人数是女生的多少倍怎么计算? 3....
  • java处理环比增长率

    千次阅读 2020-08-18 16:32:37
    公式:环比增长率=(当月数据-上月数据)/上月数据 第一步首先统计出某年12个月+上年最后一个月份的数据,sql如下: SELECT a.`month` AS `month`, ifnull( b.winOrderNum, 0 ) as winOrderNum, ifnull( b....
  • 早晨起得太早,昨晚睡得太晚,一天都迷迷糊糊的。中午虽然睡了半个小时,可是依然没有缓过来。...effective java 通过函数来作为策略通过函数作为策略有两个要注意的地方:使用接口作为策略传入如果长...
  • java统计系统工具类

    万次阅读 2019-08-06 15:28:41
    在某些常见的图形、表格统计系统中,往往需要计算同比环比等等,下面是自己整理的常用统计工具类方法 import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; ...
  • // 同理近几周直接更改对应的周数差值即可 SELECT * FROM `TB` WHERE YEARWEEK(date_format(q_time,'%Y-%m-%d')) = YEARWEEK(now())-1;

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 821
精华内容 328
关键字:

java 同比环比数据

java 订阅
友情链接: SerialObject.zip