feat(RecordIotenvInstantMapper): 支持秒级回溯并优化SQL查询结构

main
zangch@mesnac.com 3 months ago
parent d646df5b8a
commit 4ccf639cd2

@ -508,49 +508,66 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
FROM ${tableName} t1
LEFT JOIN ems_base_monitor_info ebmi ON t1.monitorId = ebmi.monitor_code
INNER JOIN (
SELECT
t.monitorId,
CAST(DATEDIFF(MINUTE, '1970-01-01', t.recodeTime) / #{recordIotenvInstant.samplingInterval} AS BIGINT) as time_slot,
MAX(t.recodeTime) as max_time
FROM ${tableName} t
LEFT JOIN ems_base_monitor_info ebmi2 ON t.monitorId = ebmi2.monitor_code
<where>
<if test="recordIotenvInstant.monitorId != null and recordIotenvInstant.monitorId != ''">
AND t.monitorId = #{recordIotenvInstant.monitorId}
</if>
<if test="recordIotenvInstant.params.beginRecordTime != null and recordIotenvInstant.params.endRecordTime != null">
AND t.recodeTime &gt;= #{recordIotenvInstant.params.beginRecordTime}
AND t.recodeTime &lt;= #{recordIotenvInstant.params.endRecordTime}
</if>
<if test="recordIotenvInstant.monitorIds != null and recordIotenvInstant.monitorIds.length > 0">
AND t.monitorId IN
<foreach collection="recordIotenvInstant.monitorIds" item="monitorId" open="(" separator="," close=")">
#{monitorId}
</foreach>
</if>
AND (t.temperature IS NULL OR t.temperature BETWEEN 0 AND 79)
AND (t.humidity IS NULL OR t.humidity BETWEEN 0 AND 79)
AND (t.noise IS NULL OR t.noise BETWEEN 0 AND 79)
<!-- 用子查询先计算 time_slot避免 SELECT 和 GROUP BY 中各自生成不同的 ? 占位符导致 SQL Server 报错 -->
SELECT monitorId, time_slot, MAX(recodeTime) AS max_time FROM (
SELECT
t.monitorId,
CAST(
<choose>
<!-- 这里把时间粒度切到秒,是为了真正支持"秒级回溯",而不是继续按分钟抽样后伪装成秒级结果。 -->
<when test="recordIotenvInstant.samplingGranularity == 'SECOND' or recordIotenvInstant.samplingGranularity == 'second'">
DATEDIFF(SECOND, '1970-01-01', t.recodeTime)
</when>
<when test="recordIotenvInstant.samplingGranularity == 'HOUR' or recordIotenvInstant.samplingGranularity == 'hour'">
DATEDIFF(HOUR, '1970-01-01', t.recodeTime)
</when>
<otherwise>
DATEDIFF(MINUTE, '1970-01-01', t.recodeTime)
</otherwise>
</choose>
/ #{recordIotenvInstant.samplingInterval} AS BIGINT
) as time_slot,
t.recodeTime
FROM ${tableName} t
LEFT JOIN ems_base_monitor_info ebmi2 ON t.monitorId = ebmi2.monitor_code
<where>
<if test="recordIotenvInstant.monitorId != null and recordIotenvInstant.monitorId != ''">
AND t.monitorId = #{recordIotenvInstant.monitorId}
</if>
<if test="recordIotenvInstant.params.beginRecordTime != null and recordIotenvInstant.params.endRecordTime != null">
AND t.recodeTime &gt;= #{recordIotenvInstant.params.beginRecordTime}
AND t.recodeTime &lt;= #{recordIotenvInstant.params.endRecordTime}
</if>
<if test="recordIotenvInstant.monitorIds != null and recordIotenvInstant.monitorIds.length > 0">
AND t.monitorId IN
<foreach collection="recordIotenvInstant.monitorIds" item="monitorId" open="(" separator="," close=")">
#{monitorId}
</foreach>
</if>
AND (t.temperature IS NULL OR t.temperature BETWEEN 0 AND 79)
AND (t.humidity IS NULL OR t.humidity BETWEEN 0 AND 79)
AND (t.noise IS NULL OR t.noise BETWEEN 0 AND 79)
<!-- 过滤虚拟设备忽略is_ammeter为0的虚拟设备 -->
-- AND (ebmi2.is_ammeter IS NULL OR ebmi2.is_ammeter != '0')
<!-- 过滤虚拟设备忽略is_ammeter为0的虚拟设备 -->
-- AND (ebmi2.is_ammeter IS NULL OR ebmi2.is_ammeter != '0')
<!-- 根据设备类型过滤掉负责字段为0的数据 -->
<!-- 对于没有设备信息的记录保留所有非0数据 -->
AND (
-- 温度设备(type=5)过滤温度为0的数据
(ebmi2.monitor_type = 5 AND t.temperature > 0) OR
-- 温湿度设备(type=6)过滤温度和湿度都为0的数据
(ebmi2.monitor_type = 6 AND (t.temperature > 0 OR t.humidity > 0)) OR
-- 噪声设备(type=7)过滤噪声为0的数据
(ebmi2.monitor_type = 7 AND t.noise > 0) OR
-- 振动设备(type=10)过滤振动相关字段都为0的数据
(ebmi2.monitor_type = 10 AND (t.vibration_speed > 0 OR t.vibration_displacement > 0 OR t.vibration_acceleration > 0 OR t.vibration_temp > 0)) OR
-- 其他类型设备或无设备信息:保留所有有效数据
(ebmi2.monitor_type NOT IN (5, 6, 7, 10) OR ebmi2.monitor_type IS NULL)
)
</where>
GROUP BY t.monitorId, CAST(DATEDIFF(MINUTE, '1970-01-01', t.recodeTime) / #{recordIotenvInstant.samplingInterval} AS BIGINT)
<!-- 根据设备类型过滤掉负责字段为0的数据 -->
<!-- 对于没有设备信息的记录保留所有非0数据 -->
AND (
-- 温度设备(type=5)过滤温度为0的数据
(ebmi2.monitor_type = 5 AND t.temperature > 0) OR
-- 温湿度设备(type=6)过滤温度和湿度都为0的数据
(ebmi2.monitor_type = 6 AND (t.temperature > 0 OR t.humidity > 0)) OR
-- 噪声设备(type=7)过滤噪声为0的数据
(ebmi2.monitor_type = 7 AND t.noise > 0) OR
-- 振动设备(type=10)过滤振动相关字段都为0的数据
(ebmi2.monitor_type = 10 AND (t.vibration_speed > 0 OR t.vibration_displacement > 0 OR t.vibration_acceleration > 0 OR t.vibration_temp > 0)) OR
-- 其他类型设备或无设备信息:保留所有有效数据
(ebmi2.monitor_type NOT IN (5, 6, 7, 10) OR ebmi2.monitor_type IS NULL)
)
</where>
) sub
GROUP BY sub.monitorId, sub.time_slot
) t2 ON t1.monitorId = t2.monitorId AND t1.recodeTime = t2.max_time
</foreach>
ORDER BY monitorId ASC, recodeTime ASC

Loading…
Cancel
Save