一、数据准备
下表是小明最近一年的旅游记录
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年每个月出去旅游了多少次及消费
- 统计自己这一年每个城市旅行的平均间隔时间
二、按月统计
sql
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折现柱状图中直观地展示出来
javascript
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查询出每个城市的名字和旅游日期,同时按城市排序
sql
SELECT city_name,create_date FROM travel
order by city_name asc,create_date asc
2,使用java分组方法将数据按城市分组成一个map
java
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图表中
javascript
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
]
}
]
};
实际效果如下图:由图可见,小明去上海的频率最高