[英]SQL query to get latest non null value of columns grouping by a column
I have a table in MySQL table, which looks like我在 MySQL 表中有一个表,看起来像
+--------------------------+------------+-----------------+---------+------+-------+-------------+-------------------------+----------------------------+-------+-------+
| deviceID | date | timestamp | counter | rssi | vavId | nvo_airflow | nvo_air_damper_position | nvo_temperature_sensor_pps | block | floor |
+--------------------------+------------+-----------------+---------+------+-------+-------------+-------------------------+----------------------------+-------+-------+
| fd00::212:4b00:1957:d616 | 2020-02-29 | 12:40:01.513066 | 805 | 91 | 7 | NULL | NULL | 26.49 | NULL | ABCD |
| fd00::212:4b00:1957:d616 | 2020-02-29 | 12:41:01.542272 | 807 | 94 | 5 | 50 | 64 | 26.37 | NULL | ABCD |
| fd00::212:4b00:1957:d616 | 2020-02-29 | 12:43:01.699023 | 811 | 90 | 7 | 50 | NULL | NULL | NULL | ABCD |
| fd00::212:4b00:1957:d616 | 2020-02-29 | 12:46:01.412259 | 817 | 64 | 26 | NULL | NULL | 25.85 | NULL | ABCD |
| fd00::212:4b00:1957:d616 | 2020-02-29 | 12:48:01.576133 | 821 | 91 | 26 | 55 | 42 | NULL | NULL | ABCD |
| fd00::212:4b00:1957:d616 | 2020-02-29 | 12:49:01.529593 | 823 | 91 | 7 | 45 | 72 | NULL | NULL | ABCD |
I want to get the latest non null data of 3 columns(nvo_airflow, nvo_air_damper_position, nvo_temperature_sensor_pps) for each vavId.我想为每个 vavId 获取 3 列(nvo_airflow、nvo_air_damper_position、nvo_temperature_sensor_pps)的最新非空数据。
My result should look something like我的结果应该看起来像
vavId,nvo_airflow,nvo_air_damper_position,nvo_temperature_sensor_pps
5,50,64,26.37
7,45,72,26.49
26,55,42,25.85
I have written a sql query for the same,我已经为此编写了一个 sql 查询,
SELECT airflow_table.nvo_airflow,damper_position_table.nvo_air_damper_position,temperature_sensor_table.nvo_temperature_sensor_pps,temperature_sensor_table.vavId
FROM(
((SELECT t1.date,t1.timestamp,t1.nvo_airflow,t1.vavId
FROM
(SELECT * FROM vavDataOptimized where date='2020-02-29')t1
INNER JOIN
(SELECT max(timestamp) as recent_timestamp,vavId FROM vavDataOptimized where date='2020-02-29' and `nvo_airflow` is not null GROUP BY vavId)t2
ON (t1.timestamp = t2.recent_timestamp and t1.vavId = t2.vavId)
ORDER BY vavId) airflow_table
inner join
(SELECT t1.date,t1.timestamp,t1.nvo_air_damper_position,t1.vavId
FROM
(SELECT * FROM vavDataOptimized where date='2020-02-29')t1
INNER JOIN
(SELECT max(timestamp) as recent_timestamp,vavId FROM vavDataOptimized where date='2020-02-29' and `nvo_air_damper_position` is not null GROUP BY vavId)t2
ON (t1.timestamp = t2.recent_timestamp and t1.vavId = t2.vavId)
ORDER BY vavId) damper_position_table ON airflow_table.vavId = damper_position_table.vavId)
inner join
(SELECT t1.date,t1.timestamp,t1.nvo_temperature_sensor_pps,t1.vavId
FROM
(SELECT * FROM vavDataOptimized where date='2020-02-29')t1
INNER JOIN
(SELECT max(timestamp) as recent_timestamp,vavId FROM vavDataOptimized where date='2020-02-29' and `nvo_temperature_sensor_pps` is not null GROUP BY vavId)t2
ON (t1.timestamp = t2.recent_timestamp and t1.vavId = t2.vavId)
ORDER BY vavId) temperature_sensor_table on airflow_table.vavId = temperature_sensor_table.vavId);
What I am trying to do is getting the latest value for each of nvo_airflow, nvo_air_damper_position, nvo_temperature_sensor_pps for each vav as three intermediate tables and then trying to do a inner join on the tables.我想要做的是获取每个 vav 的 nvo_airflow、nvo_air_damper_position、nvo_temperature_sensor_pps 的最新值作为三个中间表,然后尝试对表进行内部连接。
This query is taking a lot of time to time and not getting executed.这个查询需要花费很多时间并且没有被执行。 I am not sure if I am doing in it an optimized way.
我不确定我是否以优化的方式在做。 Am I doing something wrong, or is there a better way of doing this?
我做错了什么,还是有更好的方法来做到这一点?
Does something like this fits your needs?这样的事情是否符合您的需求?
select vavId,nvo_airflow,nvo_air_damper_position,nvo_temperature_sensor_pps
from
(select vavId, @rownum1 := @rownum1 + 1 as rownum1 from
(select vavId
from vavDataOptimized
where vavId is not NULL
ORDER BY date1,timestamp1 DESC LIMIT 3) a
CROSS JOIN (SELECT @rownum1 := 0) v) a,
(select nvo_airflow, @rownum2 := @rownum2 + 1 as rownum2 from
(select nvo_airflow
from vavDataOptimized
where nvo_airflow is not NULL
ORDER BY date1,timestamp1 DESC LIMIT 3) b
CROSS JOIN (SELECT @rownum2 := 0) v) b,
(select nvo_air_damper_position, @rownum3 := @rownum3 + 1 as rownum3 from
(select nvo_air_damper_position
from vavDataOptimized
where nvo_air_damper_position is not NULL
ORDER BY date1,timestamp1 DESC LIMIT 3) c
CROSS JOIN (SELECT @rownum3 := 0) v) c,
(select nvo_temperature_sensor_pps, @rownum4 := @rownum4 + 1 as rownum4 from
(select nvo_temperature_sensor_pps
from vavDataOptimized
where nvo_temperature_sensor_pps is not NULL
ORDER BY date1,timestamp1 DESC LIMIT 3) d
CROSS JOIN (SELECT @rownum4 := 0) v) d
where rownum1 = rownum2
and rownum1 = rownum3
and rownum1 = rownum4
Here is the fiddle : https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=57539e363b668038547df037b15f0dee这是小提琴: https ://dbfiddle.uk/ ? rdbms = mysql_8.0 & fiddle =57539e363b668038547df037b15f0dee
Here is one option of doing it.这是这样做的一种选择。 What i have done is to first rank the records on the basis of latest value of the attribute columns which are not null(eg: airflow_flg=1 implies ranks by not null values only)
我所做的是首先根据不为空的属性列的最新值对记录进行排名(例如:airflow_flg=1 仅表示非空值的排名)
After that a union of all the three would get the values you are looking for.之后,所有三个的联合将获得您正在寻找的值。
with data
as (
select *
,case when nvo_airflow is null then 0 else 1 end as airflow_flg
,case when nvo_air_damper_position is null then 0 else 1 end as damper_flg
,case when nvo_temperature_sensor_pps is null then 0 else 1 end as sensor_flg
,row_number() over(partition by case when nvo_airflow is null then 0 else 1 end,deviceid,vavid order by timestamp1 desc) as rnk_airflow
,row_number() over(partition by case when nvo_air_damper_position is null then 0 else 1 end,deviceid,vavid order by timestamp1 desc) as rnk_damper
,row_number() over(partition by case when nvo_temperature_sensor_pps is null then 0 else 1 end,deviceid,vavid order by timestamp1 desc) as rnk_sensor
from t
)
,concat_data
as (
select deviceid
,vavid
,nvo_airflow as val
,'nvo_airflow' as txt
from data
where airflow_flg=1
and rnk_airflow=1
union all
select deviceid
,vavid
,nvo_air_damper_position as val
,'nvo_air_damper_position' as txt
from data
where damper_flg=1
and rnk_damper=1
union all
select deviceid
,vavid
,nvo_temperature_sensor_pps as val
,'nvo_temperature_sensor_pps' as txt
from data
where sensor_flg=1
and rnk_sensor=1
)
select deviceid
,vavid
,max(case when txt='nvo_airflow' then val end) as nvo_airflow
,max(case when txt='nvo_air_damper_position' then val end) as nvo_air_damper_position
,max(case when txt='nvo_temperature_sensor_pps' then val end) as nvo_temperature_sensor_pps
from concat_data
group by deviceid
,vavid
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=5440a6e55e7b9a82596f57840dc38083 https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=5440a6e55e7b9a82596f57840dc38083
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.