using Entity.Ammeter; using HybirdFrameworkCore.Autofac.Attribute; using Repository.Ammeter; namespace Service.Ammeter; [Scope("SingleInstance")] public class EmeterEnergyChangeService : BaseServices { private readonly EmeterEnergyChangeRepository _emeterEnergyChangeRep; public EmeterEnergyChangeService(EmeterEnergyChangeRepository emeterEnergyChangeRep) { _emeterEnergyChangeRep = emeterEnergyChangeRep; } public async Task> SevenDaysElectrical() { // 根据code分组,取最近7天数据,每天最大值-最小值=当日用电量,如果当天目前只有一条数据,取当天最大值-前一天最大值=当天耗电量 string sql = @" WITH daily_max_min AS ( SELECT `code`, DATE(`upload_time`) AS `UploadTime`, MAX(`value`) AS `MaxValue`, MIN(`value`) AS `MinValue` FROM `emeter_energy_change` WHERE `upload_time` >= NOW() - INTERVAL 8 DAY GROUP BY `code`, DATE(`upload_time`) ), previous_day_max AS ( SELECT `code`, `UploadTime`, LAG(`MaxValue`) OVER (PARTITION BY `code` ORDER BY `UploadTime`) AS `PreviousMaxValue` FROM daily_max_min ) SELECT d.`code`, d.`UploadTime`, CASE WHEN d.`MaxValue` = d.`MinValue` THEN COALESCE(d.`MaxValue` - p.`PreviousMaxValue`, d.`MaxValue`) ELSE d.`MaxValue` - d.`MinValue` END AS `Value` FROM daily_max_min d LEFT JOIN previous_day_max p ON d.`code` = p.`code` AND d.`UploadTime` = p.`UploadTime` WHERE d.`UploadTime` >= NOW() - INTERVAL 7 DAY ORDER BY d.`code`, d.`UploadTime`; "; List emeterEnergies = await _emeterEnergyChangeRep.SqlQueryable(sql); return emeterEnergies; } public async Task> GetAllElectricalData() { string sql = @" SELECT code, MAX(value) - MIN(value) AS Value FROM emeter_energy_change GROUP BY code ORDER BY code; "; List emeterEnergies = await _emeterEnergyChangeRep.SqlQueryable(sql); return emeterEnergies; } public async Task> GetTodayHourlyElectricalData() { string sql = @" WITH hourly_max_min AS ( SELECT `code`, DATE_FORMAT(`upload_time`, '%Y-%m-%d %H:00:00') AS `Hour`, MAX(`value`) AS `MaxValue`, MIN(`value`) AS `MinValue`, COUNT(*) AS `record_count` FROM `emeter_energy_change` WHERE DATE(`upload_time`) = CURDATE() GROUP BY `code`, DATE_FORMAT(`upload_time`, '%Y-%m-%d %H:00:00') ), previous_hour_max AS ( SELECT `code`, `Hour`, LAG(`MaxValue`) OVER (PARTITION BY `code` ORDER BY `Hour`) AS `PreviousMaxValue` FROM `hourly_max_min` ) SELECT h.`code`, h.`Hour`, CASE WHEN h.`record_count` > 1 THEN h.`MaxValue` - h.`MinValue` ELSE h.`MaxValue` - COALESCE(p.`PreviousMaxValue`, 0) END AS `Value` FROM `hourly_max_min` h LEFT JOIN `previous_hour_max` p ON h.`code` = p.`code` AND h.`Hour` = p.`Hour` ORDER BY h.`code`, h.`Hour`; "; List emeterEnergies = await _emeterEnergyChangeRep.SqlQueryable(sql); return emeterEnergies; } }