1.条件:报警信息表sensor_warning
2.需求:
查询当前车厢的、不同设备的、所有处理未完成的、不同报警原因的、时间最新的数据集合,最后按设备id或报警时间排序
3.原始sql,不满足实际情况
SELECT
a.id,
a.sensor_type,
a.device_status,
a.train_no,
a.device_id,
a.sensor_no,
a.carriage_no,
a.process_progress,
a.handle_person,
a.create_time,
a.position,
a.update_time,
a.reason
FROM
sensor_warning AS a
JOIN (
SELECT
max( b.device_id ) AS device_id,
max( b.create_time ) AS create_time
FROM
sensor_warning AS b
WHERE
b.process_progress IN ( '0', '1' )
AND warning_type = 0
AND b.carriage_no = 'CARID-008'
GROUP BY
b.device_id
) AS m ON a.device_id = m.device_id
AND a.create_time = m.create_time
ORDER BY
a.device_id
4.为什么不满足实际情况?
上面的sql只能查出当前车厢的、不同设备的、所有处理未完成的、时间最新的数据集合。并没有根据reason分类。
而且这里reason字段中的数据还比较特殊,例举reason字段中的个别报警原因就知道了:
转向架振动超阈值:1.23m/s²;
转向架振动超阈值:0.48m/s²
车体振动超阈值:-0.24m/s²
车体振动超阈值:-0.55m/s²
我们可以看到reason中存在数值,如果按照上面的sql查询,那么上述的4条数据都会被查出来,而实际上只有两条数据才是我们想要的结果。
5.mysql解决方案
使用字符串截取函数SUBSTRING_INDEX(),按照冒号截取,因为数据中有中文冒号和英文冒号所以这里做了两次截取。
SELECT
a.device_id,
SUBSTRING_INDEX( SUBSTRING_INDEX( a.reason, ':', 1 ), ':', 1 ) reason,
max(a.create_time) AS create_time
FROM
(
SELECT
id,
sensor_type,
device_status,
train_no,
device_id,
sensor_no,
carriage_no,
process_progress,
handle_person,
create_time,
position,
update_time,
reason
FROM
sensor_warning
WHERE
process_progress IN ( '0', '1' )
AND warning_type = 0
AND carriage_no = 'CARID-008'
ORDER BY
create_time DESC
) a
GROUP BY
a.device_id,
SUBSTRING_INDEX( SUBSTRING_INDEX( a.reason, ':', 1 ), ':', 1 )
ORDER BY a.device_id
6.达梦数据库解决方案
(ps:同orcale)
然而达梦数据库中并不支持SUBSTRING_INDEX()函数,达梦这里使用substr()函数。
substr函数格式 (字符截取函数)
格式1: substr(string string, int a, int b);
格式2:substr(string string, int a) ;
解析:
格式1:
1、string 需要截取的字符串
2、a 截取字符串的开始位置(注:当a等于0或1时,都是从第一位开始截取)
3、b 要截取的字符串的长度
格式2:
1、string 需要截取的字符串
2、a 可以理解为从第a个字符开始截取后面所有的字符串。
6.1.达梦数据库解决方案1
SELECT
a.id,
a.device_id,
a.create_time,
a.reason
FROM
sensor_warning AS a
JOIN (
SELECT
b.device_id device_id,
substr( b.reason, 1, 7 ) reason,
max( b.id ) AS id,
max( b.create_time ) AS create_time
FROM
sensor_warning AS b
WHERE
process_progress IN ( '0', '1' )
AND warning_type = 0
AND carriage_no = 'CARID-008'
GROUP BY
b.device_id,
substr( b.reason, 1, 7 )
) AS m ON a.id = m.id
ORDER BY
a.create_time
6.2.达梦数据库解决方案2
SELECT
a.device_id,
substr( a.reason, 1, 7 ) reason,
max( a.create_time ) AS create_time
FROM
(
SELECT
id,
device_id,
carriage_no,
create_time,
reason
FROM
sensor_warning
WHERE
process_progress IN ( '0', '1' )
AND warning_type = 0
AND carriage_no = 'CARID-008'
) a
GROUP BY
a.device_id,
substr( a.reason, 1, 7 )
ORDER BY
a.create_time