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

    相关概念

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

    背景

    项目中使用了不同种数据库,为了减少

    展开全文
  • java处理环比增长率

    2020-08-18 16:32:37
    公式:环比增长率=(当月数据-上月数据)/上月数据 第一步首先统计出某年12个月+上年最后一个月份的数据,sql如下: SELECT a.`month` AS `month`, ifnull( b.winOrderNum, 0 ) as winOrderNum, ifnull( b....

    公式:环比增长率=(当月数据-上月数据)/上月数据

    第一步首先统计出某年12个月+上年最后一个月份的数据,sql如下:

      SELECT
            a.`month` AS `month`,
            ifnull( b.winOrderNum, 0 ) as winOrderNum,
            ifnull( b.winOrderAmt, '0.00' ) as winOrderAmt
            FROM
                (
    		SELECT
    			CONCAT(#{date}-1,'-12') AS `month` UNION
            SELECT
                CONCAT(#{date},'-01') AS `month` UNION
            SELECT
                CONCAT(#{date},'-02') AS `month` UNION
            SELECT
                CONCAT(#{date},'-03') AS `month` UNION
            SELECT
                CONCAT(#{date},'-04') AS `month` UNION
            SELECT
                CONCAT(#{date},'-05') AS `month` UNION
            SELECT
                CONCAT(#{date},'-06') AS `month` UNION
            SELECT
                CONCAT(#{date},'-07') AS `month` UNION
            SELECT
                CONCAT(#{date},'-08') AS `month` UNION
            SELECT
                CONCAT(#{date},'-09') AS `month` UNION
            SELECT
                CONCAT(#{date},'-10') AS `month` UNION
            SELECT
                CONCAT(#{date},'-11') AS `month` UNION
            SELECT
                CONCAT( #{date},'-12') AS `month`
                ) a
                LEFT JOIN (
            SELECT
                from_unixtime( tc.create_time / 1000, '%m' ) AS `month`,
                count(tc.id) as winOrderNum,
                CAST( IFNULL( sum( tc.amount ), 0 ) / 100 AS DECIMAL ( 20, 2 ) ) AS winOrderAmt
            FROM
                trade_contract tc
            WHERE
                from_unixtime( tc.create_time / 1000, '%Y' ) = #{date}
                and tc.opportunity_id is not null
            GROUP BY
                `month`
                ) b ON a.`month` = b.`month`

    第二步java处理环比增长:list为条件查询出的集合

    需要注意的点:

    1. 将查询的数据放到map<String,Object>对象中,通过key(月份)获取相应的数据

    2. 获取当前时间的上个月日期

    3. 通过给定的公式计算环比增长

    这些都在for循环中处理完成

    
    //定义map集合
            Map<String, ContractReportDTO> map = list.stream().collect(Collectors.toMap(ContractReportDTO::getMonth, Function.identity()));
            list.stream().forEach(entity -> {
                ContractReportDTO lastContractReportDTO = map.get(DateUtils.getPreMonth(entity.getMonth()));
                if (null == lastContractReportDTO) {
                    entity.setNumRate("0");
                    entity.setAmtRate("0");
                } else {
                    //获取上月份的赢单数
                    Integer winOrderNumLast = lastContractReportDTO.getWinOrderNum();
                    if (winOrderNumLast == 0) {
                        entity.setNumRate("0");
                    } else {
                        //赢单数环比增长率=(当月数据-上月数据)/上月数据
                        BigDecimal numRate = new BigDecimal(0);
                        numRate = new BigDecimal(entity.getWinOrderNum()).subtract(new BigDecimal(winOrderNumLast)).divide(new BigDecimal(winOrderNumLast)).setScale(1, RoundingMode.HALF_UP);
                        entity.setNumRate(numRate.toString());
                    }
                    //获取上月份的赢单金额
                    String winOrderAmtLast = lastContractReportDTO.getWinOrderAmt();
                    if ("0.00".equals(winOrderAmtLast)) {
                        entity.setAmtRate("0");
                    } else {
                        //赢单金额环比增长率
                        BigDecimal amtRate = new BigDecimal(0);
                        amtRate = new BigDecimal(entity.getWinOrderAmt()).subtract(new BigDecimal(winOrderAmtLast)).divide(new BigDecimal(winOrderAmtLast)).setScale(1, RoundingMode.HALF_UP);
                        entity.setAmtRate(amtRate.toString());
                    }
                }
            });
            list.remove(0);

    获取当前时间的上个月日期方法这里也一并提供下:

    	/**
    	 * 获取指定月份的上一月日期
    	 */
    	public static String getPreMonth(String month) {
    		try {
    			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
    			return sdf.format(org.apache.commons.lang.time.DateUtils.addMonths(sdf.parse(month), -1));
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		return "";
    	}

     

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

    千次阅读 2020-08-31 14:39:28
    Java计算同比环比 同比环比计算基本概念和计算公式 同比率:本年数据比上一年数据增长或减少的比率 同比率计算公式:rate = (本年数据 - 前一年数据) / 前一年数据 实例:2020年10月游客数量为80W,2019年10月游客...

    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时间计算同比环比周的问题

    千次阅读 2020-03-18 17:16:23
    2、同时需要计算对应的去年同比时间和环比(就是上一个时间段,周的2020-03环比就是2020-04)时间, 3、同时还要获取周和月的开始时间和结束时间,比如周2020-02的开始是2020-01-06,结束时间是2020-01-12, 4、周...

    问题描述:

    在业务中会有传不同日期格式,

    1、有天(2020-02-29),周(2020-03第三周),月(2020-02二月份),

    2、同时需要计算对应的去年同比时间和环比(就是上一个时间段,周的2020-03环比就是2020-04)时间,

    3、同时还要获取周和月的开始时间和结束时间,比如周2020-02的开始是2020-01-06,结束时间是2020-01-12,

    4、周的第一天从周一开始算,周跨年有大于等于四天在今年就算今年最后一周,否则就是明年的第一周

    最麻烦的就是查询周的同比和环比问题,因为涉及跨年和周一是第一天的特殊情况,最后在摸索了一天后学会了java的Calendar工具怎么用了,直接上通用方法。

    下面这个方法是获取同比环比周的第一天日期,第二个方法是把这个日期转换成周格式(xxxx-xx)

        /**
         * 同比环比周, xxxx-xx,
         * @param date 格式必须是xxxx-xx
         * @param type 0是当前
         *             1是同比
         *             2是环比
         */
        public static Date getCompareWeek(String date, int type) {
            int year = Integer.parseInt(date.substring(0, 4));
            int week = Integer.parseInt(date.substring(5, 7));
    
            Calendar cal = Calendar.getInstance();
            cal.setFirstDayOfWeek(Calendar.MONDAY);
            cal.setMinimalDaysInFirstWeek(4);
            cal.set(Calendar.YEAR, year);
            cal.set(Calendar.WEEK_OF_YEAR, week);
            int plus;
            if (type == 1)
                if (week == 53)
                    plus = cal.getWeeksInWeekYear();
                else
                    plus = 52;
            else if (type == 2)
                plus = 1;
            else
                plus = 0;
            cal.add(Calendar.WEEK_OF_YEAR, -plus);
    
            return cal.getTime();
        }
    

    备注:3月21号修改,之前有个bug,因为calendar在判断周的日期的时候会根据当前时间的周时间变化,例如今天周五,同比去年的第五周就会到去年第五周的周五,同理如果是今天是周一也就会到去年第五周的周一,这样有可能会有问题了。具体还是自己试验一下会更清楚一些。例如2021-01的同比和环比周问题

        /**
         * 一周最少四天,每周从周一开始是第一天,获取周格式日期  xxxx-xx
         * @return xxxx-xx
         * @throws ParseException
         */
    
        public static String getCurrentWeekWithYearStartWithMonday(Date dateDesc) {
            Calendar c = Calendar.getInstance();
            c.setTime(dateDesc);
            c.setFirstDayOfWeek(Calendar.MONDAY);
            c.setMinimalDaysInFirstWeek(4);
            Date time = c.getTime();
            int day = c.get(Calendar.DAY_OF_MONTH);
            int week = c.get(Calendar.WEEK_OF_YEAR);
            int year = c.get(Calendar.YEAR);
            if (day > 28 && week == 1) {
                year++;
            } else if (day < 4 && week == getWeeksOfYear(dateDesc)){
                year--;
            }
            return String.format("%04d-%02d", year, week);
        }
    
        public static int getWeeksOfYear(int year) {
            Calendar cal = Calendar.getInstance();
            cal.setFirstDayOfWeek(Calendar.MONDAY);
            cal.setMinimalDaysInFirstWeek(4);
            cal.set(Calendar.YEAR, year);
            return cal.getWeeksInWeekYear();
        }
        public static int getWeeksOfYear(Date date) {
            Calendar cal = Calendar.getInstance();
            cal.setFirstDayOfWeek(Calendar.MONDAY);
            cal.setMinimalDaysInFirstWeek(4);
            cal.setTime(date);
            return cal.getWeeksInWeekYear();
        }
    

    这个是中国标准的日历星期说明,所有定义都是从这里来的。

    展开全文
  • 公式:(本期数量-上期数量)/上期数量*100%) 代码: public static void main(String[] args) { Integer bcount = 119; // 本期数量 Integer scount = 158; // 上期数量 BigDecimal tests = BigDecimal....
  • 由于之前没有开发到这些东西,如今需要请各位给一条路
  • ...   环比数据是指与同年的上一期相比的数据。如果做的是周数据比较,环比就是本周数据比上周的数据;如果做的是月数据比较,环比就是本月数据比上月的数据;...环比环比增长速度和环比发展速度两...
  • Java程序员的日常—— 基于类的策略模式、List&lt;?&gt;与List、泛型编译警告、同比和环比 早晨起得太早,昨晚睡得太晚,一天都迷迷糊糊的。中午虽然睡了半个小时,可是依然没有缓过来...
  • Ureport2做环比报表

    2021-01-27 10:43:05
    报表模版如下图所示: 在上面的报表模版中,D2 单元格中的表达式为 C2 - C2[A2:-1] ,这就表示在D2...从运行结果中可以看到,第一行环比的值为0,这是因为对于第一行的 D2 单元格来说,其上一行其实是不存在...
  • 数据计算环比等比

    2020-07-10 14:41:40
    开发原因 为方便上级直观看出销售额的直观数据,添加年度、月度比较折线图和柱状图以及同比环比数据 开发方式 折线图和柱状图采用ECharts 同比环比的计算 当选择本月数据时,增加上月数量(环比)、去年本月数量(同...
  • java时间转换

    2011-12-22 15:09:56
    做项目是需要求同比和环比,在数据库中操作不是太方便,就将时间操作放在了java程序中。以下是字符串类型的时间经过减去一天,一个月,一年以后再转换为字符串类型的时间输出出来。 import java.text.Parse...
  • Java API:中文名称为Java ,就是Java提供给我们使用的预先定义的类和接口。答:应用程序接口劝说广告主要用于产品的答:成长期肘关节脱位的特有体征是 :答:肘后三角关系异常共集电极电路电压放大倍数大答:×青书...
  • 同比环比

    千次阅读 2008-06-16 10:11:00
    其实这两个需求就是我们常说的同比和环比问题,它们用关系数据库的SQL语句难于实现,而用BI中的MDX来做却轻而易举。以下例子采用的是SQL Server2005的Analysis Services中的示例库。 环比需求:本月比
  • 1. 当你的时间是时间点(2017...member [Measures].[TOTAL_MONEY_环比] as ' (([Measures].[TOTAL_MONEY] / ([Measures].[TOTAL_MONEY], [ADD_T_1].[CAL_DATE].CurrentMember.PrevMember)) - 1)', FORMAT_STRING = ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,100
精华内容 440
关键字:

java环比

java 订阅