一、数据准备
下表是小明最近一年的旅游记录
create_date | city_name | cost_money |
---|---|---|
2023-10-10 10:10:10 | 北京 | 1499 |
2023-11-11 11:11:11 | 上海 | 2999 |
2023-12-12 12:12:12 | 上海 | 1999 |
2024-01-24 12:12:12 | 北京 | 123 |
2024-01-24 12:12:12 | 上海 | 223 |
2024-02-24 12:12:12 | 广州 | 564 |
2024-02-24 12:12:12 | 北京 | 221 |
2024-02-24 12:12:12 | 上海 | 442 |
2024-03-24 12:12:12 | 广州 | 505 |
2024-04-24 12:12:12 | 上海 | 656 |
2024-05-14 12:12:12 | 上海 | 766 |
2024-05-18 12:12:12 | 广州 | 999 |
2024-05-24 12:12:12 | 上海 | 3244 |
2024-05-24 12:12:12 | 北京 | 786 |
2024-06-24 12:12:12 | 广州 | 662 |
2024-07-24 12:12:12 | 北京 | 532 |
现在小明有两个需求
- 统计自己2024年每个月出去旅游了多少次及消费
- 统计自己这一年每个城市旅行的平均间隔时间
二、按月统计
SELECT substring(a.create_date, 6, 2)::int as month, sum(a.cost_money) cost_money , sum(a.travel_count) travel_count from ( SELECT to_char(create_date, 'YYYY-MM') AS create_date, sum(CASE WHEN to_char(create_date, 'YYYY') = '2024' THEN cost_money ELSE 0 END) AS cost_money, count(CASE WHEN to_char(create_date, 'YYYY') = '2024' THEN city_name ELSE null END) AS travel_count FROM travel WHERE create_date >= '2024-01-01' AND create_date < '2024-12-31' GROUP BY to_char(create_date, 'YYYY-MM') ORDER BY create_date ) a GROUP BY substring(a.create_date, 6, 2) ::int ORDER BY month asc
复制
查询结果如下
现在把这些数据加载到echarts折现柱状图中直观地展示出来
option = { title : { text : '2024旅游统计图', textStyle :{ color:'rgba(15,64,245,1)' } }, tooltip: { trigger: 'axis', axisPointer: { type: 'cross', crossStyle: { color: '#999' } } }, xAxis: [ { type: 'category', data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月'], axisPointer: { type: 'shadow' } } ], yAxis: [ { type: 'value', name: '金额', min: 0, axisLabel: { formatter: '{value} 元' } }, { type: 'value', name: '次数', min: 0, axisLabel: { formatter: '{value} 次' } } ], series: [ { name: '消费金额', type: 'bar', tooltip: { valueFormatter: function (value) { return value + ' 元'; } }, data: [ 346, 1277,505,656,5795,662,532 ] }, { name: '旅游次数', type: 'line', yAxisIndex: 1, tooltip: { valueFormatter: function (value) { return value + ' 次'; } }, data: [2, 3, 1, 1, 4, 1,1] } ] };
复制
展示结果如下图:可以看出5月份的旅游次数最多,消费金额也是5月最多
三、按城市统计平均旅游间隔时间
1,先用sql查询出每个城市的名字和旅游日期,同时按城市排序
SELECT city_name,create_date FROM travel order by city_name asc,create_date asc
复制
2,使用java分组方法将数据按城市分组成一个map
import java.text.SimpleDateFormat; import java.util.Date; import java.util.stream.Collectors;; import java.util.List; import java.util.Map; import java.util.ArrayList; public class Main { public static void main(String[] args) { List<TravelData> list = new ArrayList<>(); list.add(new TravelData("北京","2023-10-10 10:10:10")); list.add(new TravelData("北京","2024-01-24 12:12:12")); list.add(new TravelData("北京","2024-02-24 12:12:12")); list.add(new TravelData("北京","2024-05-24 12:12:12")); list.add(new TravelData("北京","2024-07-24 12:12:12")); list.add(new TravelData("广州","2024-02-24 12:12:12")); list.add(new TravelData("广州","2024-03-24 12:12:12")); list.add(new TravelData("广州","2024-05-18 12:12:12")); list.add(new TravelData("广州","2024-06-24 12:12:12")); list.add(new TravelData("上海","2023-11-11 12:12:12")); list.add(new TravelData("上海","2023-12-12 12:12:12")); list.add(new TravelData("上海","2024-01-24 12:12:12")); list.add(new TravelData("上海","2024-02-24 12:12:12")); list.add(new TravelData("上海","2024-04-24 12:12:12")); list.add(new TravelData("上海","2024-05-14 12:12:12")); list.add(new TravelData("上海","2024-05-24 12:12:12")); // 以上数据可使用数据库sql查询 Map<String, List<TravelData>> maps = list.stream().collect(Collectors.groupingBy(TravelData::getCityName)); maps.forEach((key, dateList) -> { long timeTotal = 0; for (int i = 0; i < dateList.size(); i++) { if(i < dateList.size() - 1){ TravelData nextItem = dateList.get(i + 1); timeTotal += nextItem.getCreateDate() - dateList.get(i).getCreateDate(); } } long avgTime = timeTotal/(dateList.size() - 1); // 单位为天 System.out.println(key + ",平均间隔 = " + avgTime/(1000*60*60*24)); } ); } static class TravelData{ String cityName; Date createDate; SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public TravelData(String name,String date){ this.cityName = name; try{ this.createDate = dateFormat.parse(date); }catch(Exception e){ System.out.println(e.getMessage()); } } public String getCityName(){ return cityName; } public Long getCreateDate(){ return createDate.getTime(); } public String toString(){ return "city:"+cityName + ",create_date:"+dateFormat.format(createDate); } } }
复制
以上java代码输出结果为
把数据装载到ECharts图表中
option = { title : { text : '2024旅游城市MTBF', textStyle :{ color:'rgba(15,64,245,1)' } }, tooltip: { trigger: 'axis', axisPointer: { type: 'cross', crossStyle: { color: '#999' } } }, xAxis: [ { type: 'category', data: ['北京', '上海', '广州'], axisPointer: { type: 'shadow' } } ], yAxis: [ { type: 'value', name: '间隔', min: 0, axisLabel: { formatter: '{value} ' } } ], series: [ { name: '平均旅游间隔', type: 'bar', tooltip: { valueFormatter: function (value) { return value + ' 天'; } }, data: [ 72, 32, 40 ] } ] };
复制
实际效果如下图:由图可见,小明去上海的频率最高