1.条件:报警信息表sensor_warning

查询满足条件的最新数据(逐步优化,mysql、达梦数据库)-LMLPHP

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
12-09 03:10