MySQL 统计图数据(分别查询每周、每月、每年的数据,进行分组展示SQL)

项目上要做一个统计图,要分别按本周、本月、本年度展示数据,每周的是用循环单个查询的,后来想到每月、每年的可以一个sql直接统出来。

先看下结果,不是自己找的可以划走了,节省时间:
MySQL 统计图数据(分别查询每周、每月、每年的数据,进行分组展示SQL)_第1张图片
MySQL 统计图数据(分别查询每周、每月、每年的数据,进行分组展示SQL)_第2张图片
一: 统计每月、每天数据
1.先建一张表,这两个sql都会用到,用于笛卡尔计算。

DROP TABLE IF EXISTS `t_calendar_auxiliary`;
CREATE TABLE `t_calendar_auxiliary`  (
  `i` int(11) NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '日历辅助表' ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of t_calendar_auxiliary
-- ----------------------------
INSERT INTO `t_calendar_auxiliary` VALUES (0);
INSERT INTO `t_calendar_auxiliary` VALUES (1);
INSERT INTO `t_calendar_auxiliary` VALUES (2);
INSERT INTO `t_calendar_auxiliary` VALUES (3);
INSERT INTO `t_calendar_auxiliary` VALUES (4);
INSERT INTO `t_calendar_auxiliary` VALUES (5);
INSERT INTO `t_calendar_auxiliary` VALUES (6);
INSERT INTO `t_calendar_auxiliary` VALUES (7);
INSERT INTO `t_calendar_auxiliary` VALUES (8);
INSERT INTO `t_calendar_auxiliary` VALUES (9);

SET FOREIGN_KEY_CHECKS = 1;

2.统计每年数据
1)sql语句

SELECT LEFT
	( temp.date, 7 ),
	IFNULL ( nums, 0 ) nums 
FROM
	(
	SELECT
		adddate( '2021-01-01', INTERVAL numlist.id MONTH ) AS 'date' 
	FROM
		(
		SELECT
			* 
		FROM
			( SELECT n1.i + n10.i * 10 AS id FROM t_calendar_auxiliary n1 CROSS JOIN num AS n10 ) a 
		WHERE
			a.id <= 11 
		) AS numlist 
	WHERE
		adddate( '2021-01-01', INTERVAL numlist.id MONTH ) <= '2021-12-01' 
	) temp
	LEFT JOIN (
	SELECT LEFT
		( DATE_FORMAT( base_create_time, "%Y-%m-%d" ), 7 ) AS udate,
		count( u.base_id ) nums,
		u.type,
		u.base_id 
	FROM
		XXX(你的表名) u 
	WHERE
		u.type = '0' 
	GROUP BY
		udate 
	) u ON LEFT ( temp.date, 7 ) = u.udate 
ORDER BY
	temp.date

sql说明见下图:
MySQL 统计图数据(分别查询每周、每月、每年的数据,进行分组展示SQL)_第3张图片
2)Java 关键代码及工具类
工具类

/**
 * User: dxk
 * Date: 2021/1/27
 * Time: 9:55
 * Description: 数字大小写转换
 */
public class DigitalLowerToUpper {
     
    private static final Map<String, String> digitDict = new HashMap<String, String>();

    static {
     

        digitDict.put("1", "一");
        digitDict.put("2", "二");
        digitDict.put("3", "三");
        digitDict.put("4", "四");
        digitDict.put("5", "五");
        digitDict.put("6", "六");
        digitDict.put("7", "日");
    }

    /**
     * 转换
     *
     * @param obj
     * @return
     */
    public static String upper(String obj) {
     
            return digitDict.get(obj);
    }

    /**
     * 获取当前月的第一天和最后一天
     * @return
     */
    public static Map<String,String> getDay(){
     
       Map<String,String> map = new HashMap<>();

        Calendar cale = null;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String firstday, lastday;
        cale = Calendar.getInstance();
        cale.add(Calendar.MONTH, 0);
        cale.set(Calendar.DAY_OF_MONTH, 1);
        firstday = format.format(cale.getTime());
        cale = Calendar.getInstance();
        cale.add(Calendar.MONTH, 1);
        cale.set(Calendar.DAY_OF_MONTH, 0);
        lastday = format.format(cale.getTime());
        int days = cale.getActualMaximum(Calendar.DAY_OF_MONTH);

        map.put("firstday",firstday);
        map.put("lastday",lastday);
        map.put("days", String.valueOf(days));

        return map;
    }

    /**
     * 获取进30天开始结束时间附近
     * @return
     */
    public static Map<String,String> getDayNearby(){
     
        Map<String,String> map = new HashMap<>();

        Calendar cale = null;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String firstday, lastday;
        cale = Calendar.getInstance();
        lastday = format.format(cale.getTime());
        cale.add(cale.DATE, -30);
        Date minDate = cale.getTime();
        firstday = format.format(minDate);
        map.put("firstday",firstday);
        map.put("lastday",lastday);
        map.put("days", String.valueOf(30));

        return map;
    }

    /**
     * 当前年份
     * @return
     */
    public static Map<String,String> getMonth(){
     
       Map<String,String> map = new HashMap<>();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

        Calendar currCal=Calendar.getInstance();
        int year = currCal.get(Calendar.YEAR);
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        Date currYearFirst = calendar.getTime();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        calendar.roll(Calendar.DAY_OF_YEAR, -1);
        Date currYearLast = calendar.getTime();

        map.put("firstday", format.format(currYearFirst));
        map.put("lastday", format.format(currYearLast));
        map.put("days", String.valueOf(11));

        return map;
    }
}

代码返回处理,返回样式如下图
MySQL 统计图数据(分别查询每周、每月、每年的数据,进行分组展示SQL)_第4张图片
代码处理

NewUserStatisticsVo newUserStatisticsVo = new NewUserStatisticsVo();
Map<String, Object> dataResult = new LinkedHashMap<>();

Map<String,String> months = DigitalLowerToUpper.getMonth();
List<Map<String,Object>> resDaysList = htIndexMappe.getMonth(months);
resDaysList.forEach(d ->{
     
        dataResult.put(String.valueOf(d.get("d")),d.get("nums"));
        });
    
List<Object> valuesList=new ArrayList<>(dataResult.values());
List<String> keyList=new ArrayList<>(dataResult.keySet());
newUserStatisticsVo.setKey(keyList);
newUserStatisticsVo.setValue(valuesList);

3.统计每月数据

SELECT LEFT
	( temp.date, 10 ) d,
	IFNULL ( nums, 0 ) nums 
FROM
	(
	SELECT
		adddate( '2021-01-01', INTERVAL numlist.id DAY) AS 'date' 
	FROM
		(
		SELECT
			* 
		FROM
			( SELECT n1.i + n10.i * 10 AS id FROM t_calendar_auxiliary n1 CROSS JOIN num AS n10 ) a 
		WHERE
			a.id <= 31 
		) AS numlist 
	WHERE
		adddate( '2021-01-01', INTERVAL numlist.id DAY) <= '2021-01-31' 
	) temp
	LEFT JOIN (
	SELECT LEFT
		( DATE_FORMAT( base_create_time, "%Y-%m-%d" ), 10 ) AS udate,
		count( u.base_id ) nums,
		u.type,
		u.base_id 
	FROM
		XXX(你的表名) u 
	WHERE
		u.type = '0' 
	GROUP BY
		udate 
	) u ON LEFT ( temp.date, 10 ) = u.udate 
ORDER BY
	temp.date

Over

你可能感兴趣的:(数据库,sql统计,sql每天,sql每月,sql每年)