项目上要做一个统计图,要分别按本周、本月、本年度展示数据,每周的是用循环单个查询的,后来想到每月、每年的可以一个sql直接统出来。
先看下结果,不是自己找的可以划走了,节省时间:
一: 统计每月、每天数据
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
/**
* 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;
}
}
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