|
|
@ -108,11 +108,184 @@ public class MeasureAverageService { |
|
|
|
|
|
|
|
|
logger.info("Hourly aggregation finished for {} devices", resultMap.size()); |
|
|
logger.info("Hourly aggregation finished for {} devices", resultMap.size()); |
|
|
|
|
|
|
|
|
|
|
|
// 判断是否到达每日 / 每月 / 每年聚合时间点
|
|
|
|
|
|
if (now.getHour() == 0) { |
|
|
|
|
|
aggregateLastDay(companyId, now, now.toLocalDate().minusDays(1)); // 昨天的聚合
|
|
|
|
|
|
} |
|
|
|
|
|
if (now.getDayOfMonth() == 1 && now.getHour() == 0) { |
|
|
|
|
|
aggregateLastMonth(companyId, now, now.toLocalDate().minusMonths(1)); // 上个月的聚合
|
|
|
|
|
|
} |
|
|
|
|
|
if (now.getMonthValue() == 1 && now.getDayOfMonth() == 1 && now.getHour() == 0) { |
|
|
|
|
|
aggregateLastYear(companyId, now, now.toLocalDate().minusYears(1)); // 上一年的聚合
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
} catch (SQLException e) { |
|
|
} catch (SQLException e) { |
|
|
logger.error("Hourly aggregation failed", e); |
|
|
logger.error("Hourly aggregation failed", e); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void aggregateLastDay(Long companyId, LocalDateTime now, LocalDate targetDate) { |
|
|
|
|
|
String schema = "data_center_dongjian_" + companyId; |
|
|
|
|
|
String sourceTable = "dashboard_aggregate_measure_hour"; |
|
|
|
|
|
String targetTable = "dashboard_aggregate_measure_day"; |
|
|
|
|
|
|
|
|
|
|
|
logger.info("Aggregating daily data for company: {}, date {}", companyId, targetDate); |
|
|
|
|
|
|
|
|
|
|
|
String sql = String.format( |
|
|
|
|
|
"SELECT device_id, (SUM(COALESCE(CAST(NULLIF(average_value, '') AS DECIMAL(20,6)), 0)) / 24.0) AS avg_val, " + |
|
|
|
|
|
"MAX(max_value) AS max_val, MIN(min_value) AS min_val " + |
|
|
|
|
|
"FROM %s.%s WHERE date_year = ? AND date_month = ? AND date_day = ? GROUP BY device_id", |
|
|
|
|
|
schema, sourceTable |
|
|
|
|
|
); |
|
|
|
|
|
logger.info("sql:{}, date_year:{}, date_month:{}, date_day:{}", sql, targetDate.getYear(), targetDate.getMonthValue(), targetDate.getDayOfMonth()); |
|
|
|
|
|
|
|
|
|
|
|
String insertSql = String.format( |
|
|
|
|
|
"INSERT INTO %s.%s (device_id, average_value, max_value, min_value, date_year, date_month, date_day, aggregated_at) " + |
|
|
|
|
|
"VALUES (?, ?, ?, ?, ?, ?, ?, ?)", |
|
|
|
|
|
schema, targetTable |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
try (Connection conn = getConnection(); |
|
|
|
|
|
PreparedStatement psSelect = conn.prepareStatement(sql); |
|
|
|
|
|
PreparedStatement psInsert = conn.prepareStatement(insertSql)) { |
|
|
|
|
|
|
|
|
|
|
|
psSelect.setInt(1, targetDate.getYear()); |
|
|
|
|
|
psSelect.setInt(2, targetDate.getMonthValue()); |
|
|
|
|
|
psSelect.setInt(3, targetDate.getDayOfMonth()); |
|
|
|
|
|
ResultSet rs = psSelect.executeQuery(); |
|
|
|
|
|
|
|
|
|
|
|
while (rs.next()) { |
|
|
|
|
|
String deviceId = rs.getString("device_id"); |
|
|
|
|
|
double avg = rs.getDouble("avg_val"); |
|
|
|
|
|
double max = rs.getDouble("max_val"); |
|
|
|
|
|
double min = rs.getDouble("min_val"); |
|
|
|
|
|
|
|
|
|
|
|
psInsert.setString(1, deviceId); |
|
|
|
|
|
psInsert.setDouble(2, avg); |
|
|
|
|
|
psInsert.setDouble(3, max); |
|
|
|
|
|
psInsert.setDouble(4, min); |
|
|
|
|
|
psInsert.setInt(5, targetDate.getYear()); |
|
|
|
|
|
psInsert.setInt(6, targetDate.getMonthValue()); |
|
|
|
|
|
psInsert.setInt(7, targetDate.getDayOfMonth()); |
|
|
|
|
|
psInsert.setTimestamp(8, Timestamp.valueOf(now)); |
|
|
|
|
|
psInsert.addBatch(); |
|
|
|
|
|
} |
|
|
|
|
|
psInsert.executeBatch(); |
|
|
|
|
|
logger.info("Daily aggregation completed for {}", targetDate); |
|
|
|
|
|
|
|
|
|
|
|
} catch (SQLException e) { |
|
|
|
|
|
logger.error("Daily aggregation failed for {}", targetDate, e); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void aggregateLastMonth(Long companyId, LocalDateTime now, LocalDate targetMonth) { |
|
|
|
|
|
String schema = "data_center_dongjian_" + companyId; |
|
|
|
|
|
String sourceTable = "dashboard_aggregate_measure_day"; |
|
|
|
|
|
String targetTable = "dashboard_aggregate_measure_month"; |
|
|
|
|
|
|
|
|
|
|
|
logger.info("Aggregating monthly data for company:{}, month: {}", companyId, targetMonth.getMonthValue()); |
|
|
|
|
|
|
|
|
|
|
|
// 天数作为分母
|
|
|
|
|
|
int daysInMonth = YearMonth.of(targetMonth.getYear(), targetMonth.getMonthValue()).lengthOfMonth(); |
|
|
|
|
|
|
|
|
|
|
|
String sql = String.format( |
|
|
|
|
|
"SELECT device_id, (SUM(COALESCE(CAST(NULLIF(average_value, '') AS DECIMAL(20,6)), 0)) / %d.0) AS avg_val, " + |
|
|
|
|
|
"MAX(max_value) AS max_val, MIN(min_value) AS min_val " + |
|
|
|
|
|
"FROM %s.%s WHERE date_year = ? AND date_month = ? GROUP BY device_id", |
|
|
|
|
|
daysInMonth, schema, sourceTable |
|
|
|
|
|
); |
|
|
|
|
|
logger.info("sql:{}, date_year:{}, date_month:{}", sql, targetMonth.getYear(), targetMonth.getMonthValue()); |
|
|
|
|
|
|
|
|
|
|
|
String insertSql = String.format( |
|
|
|
|
|
"INSERT INTO %s.%s (device_id, average_value, max_value, min_value, date_year, date_month, aggregated_at) " + |
|
|
|
|
|
"VALUES (?, ?, ?, ?, ?, ?, ?)", |
|
|
|
|
|
schema, targetTable |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
try (Connection conn = getConnection(); |
|
|
|
|
|
PreparedStatement psSelect = conn.prepareStatement(sql); |
|
|
|
|
|
PreparedStatement psInsert = conn.prepareStatement(insertSql)) { |
|
|
|
|
|
|
|
|
|
|
|
psSelect.setInt(1, targetMonth.getYear()); |
|
|
|
|
|
psSelect.setInt(2, targetMonth.getMonthValue()); |
|
|
|
|
|
ResultSet rs = psSelect.executeQuery(); |
|
|
|
|
|
|
|
|
|
|
|
while (rs.next()) { |
|
|
|
|
|
String deviceId = rs.getString("device_id"); |
|
|
|
|
|
double avg = rs.getDouble("avg_val"); |
|
|
|
|
|
double max = rs.getDouble("max_val"); |
|
|
|
|
|
double min = rs.getDouble("min_val"); |
|
|
|
|
|
|
|
|
|
|
|
psInsert.setString(1, deviceId); |
|
|
|
|
|
psInsert.setDouble(2, avg); |
|
|
|
|
|
psInsert.setDouble(3, max); |
|
|
|
|
|
psInsert.setDouble(4, min); |
|
|
|
|
|
psInsert.setInt(5, targetMonth.getYear()); |
|
|
|
|
|
psInsert.setInt(6, targetMonth.getMonthValue()); |
|
|
|
|
|
psInsert.setTimestamp(7, Timestamp.valueOf(now)); |
|
|
|
|
|
psInsert.addBatch(); |
|
|
|
|
|
} |
|
|
|
|
|
psInsert.executeBatch(); |
|
|
|
|
|
|
|
|
|
|
|
logger.info("Monthly aggregation completed for {}", targetMonth); |
|
|
|
|
|
|
|
|
|
|
|
} catch (SQLException e) { |
|
|
|
|
|
logger.error("Monthly aggregation failed for {}", targetMonth, e); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void aggregateLastYear(Long companyId, LocalDateTime now, LocalDate targetYear) { |
|
|
|
|
|
String schema = "data_center_dongjian_" + companyId; |
|
|
|
|
|
String sourceTable = "dashboard_aggregate_measure_month"; |
|
|
|
|
|
String targetTable = "dashboard_aggregate_measure_year"; |
|
|
|
|
|
|
|
|
|
|
|
logger.info("Aggregating yearly data for company:{}, year: {}", companyId, targetYear.getYear()); |
|
|
|
|
|
|
|
|
|
|
|
String sql = String.format( |
|
|
|
|
|
"SELECT device_id, (SUM(COALESCE(CAST(NULLIF(average_value, '') AS DECIMAL(20,6)), 0)) / 12.0) AS avg_val," + |
|
|
|
|
|
" MAX(max_value) AS max_val, MIN(min_value) AS min_val " + |
|
|
|
|
|
"FROM %s.%s WHERE date_year = ? GROUP BY device_id", |
|
|
|
|
|
schema, sourceTable |
|
|
|
|
|
); |
|
|
|
|
|
logger.info("sql:{}, date_year:{}", sql, targetYear.getYear()); |
|
|
|
|
|
|
|
|
|
|
|
String insertSql = String.format( |
|
|
|
|
|
"INSERT INTO %s.%s (device_id, average_value, max_value, min_value, date_year, aggregated_at) " + |
|
|
|
|
|
"VALUES (?, ?, ?, ?, ?, ?)", |
|
|
|
|
|
schema, targetTable |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
try (Connection conn = getConnection(); |
|
|
|
|
|
PreparedStatement psSelect = conn.prepareStatement(sql); |
|
|
|
|
|
PreparedStatement psInsert = conn.prepareStatement(insertSql)) { |
|
|
|
|
|
|
|
|
|
|
|
psSelect.setInt(1, targetYear.getYear()); |
|
|
|
|
|
ResultSet rs = psSelect.executeQuery(); |
|
|
|
|
|
|
|
|
|
|
|
while (rs.next()) { |
|
|
|
|
|
String deviceId = rs.getString("device_id"); |
|
|
|
|
|
double avg = rs.getDouble("avg_val"); |
|
|
|
|
|
double max = rs.getDouble("max_val"); |
|
|
|
|
|
double min = rs.getDouble("min_val"); |
|
|
|
|
|
|
|
|
|
|
|
psInsert.setString(1, deviceId); |
|
|
|
|
|
psInsert.setDouble(2, avg); |
|
|
|
|
|
psInsert.setDouble(3, max); |
|
|
|
|
|
psInsert.setDouble(4, min); |
|
|
|
|
|
psInsert.setInt(5, targetYear.getYear()); |
|
|
|
|
|
psInsert.setTimestamp(6, Timestamp.valueOf(now)); |
|
|
|
|
|
psInsert.addBatch(); |
|
|
|
|
|
} |
|
|
|
|
|
psInsert.executeBatch(); |
|
|
|
|
|
|
|
|
|
|
|
logger.info("Yearly aggregation completed for {}", targetYear.getYear()); |
|
|
|
|
|
|
|
|
|
|
|
} catch (SQLException e) { |
|
|
|
|
|
logger.error("Yearly aggregation failed for {}", targetYear.getYear(), e); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 查询当前小时数据
|
|
|
// 查询当前小时数据
|
|
|
private Map<String, List<Record>> queryRecordData(Connection conn, String schema, String table, long startTs, long endTs) throws SQLException { |
|
|
private Map<String, List<Record>> queryRecordData(Connection conn, String schema, String table, long startTs, long endTs) throws SQLException { |
|
|
String sql = String.format( |
|
|
String sql = String.format( |
|
|
|