SQL 数据到 interpolate/extrapolate
SQL Data to interpolate/extrapolate
如果我有一个 table 在特定温度下保持 运行 平均 kW 使用量,并且我想获得之前未记录的温度的 kW 使用量,如何我可以得到
(A) 高于或低于温度的两个数据点进行推断。
(B) 要插入的高于和低于温度的最接近数据
table温度看起来像这样
Column | Type | Modifiers | Storage | Stats target | Description
-------------------------+------------------+-----------+---------+--------------+---------------
temperature_io_id | integer | not null | plain | |
temperature_station_id | integer | not null | plain | |
temperature_value | integer | not null | plain | | in Fahrenheit
temperature_current_kw | double precision | not null | plain | |
temperature_value_added | integer | default 1 | plain | |
temperature_kw_year_1 | double precision | default 0 | plain | |
"temperatures_pkey" PRIMARY KEY, btree (temperature_io_id, temperature_station_id, temperature_value)
(A) 建议的解决方案
我想这会更容易一些。查询将按温度值 >
或 <
我想要的温度对行进行排序,然后将结果限制为 2?这将给我高于或低于温度的两个最接近的值。当然,顺序必须是降序和升序,以确保我得到正确的项目。
SELECT * FROM temperatures
WHERE
temperature_value > ACTUALTEMP and temperature_io_id = ACTUAL_IO_id
ORDER BY
temperature_value
LIMIT 2;
我认为与上面类似,但只限制为 1 并执行 2 个查询,一个用于 >
,另一个用于 <
。不过我觉得这可以做得更好?
编辑 - 一些示例数据
temperature_io_id | temperature_station_id | temperature_value | temperature_current_kw | temperature_value_added | temperature_kw_year_1
-------------------+------------------------+-------------------+------------------------+-------------------------+-----------------------
18751 | 151 | 35 | 26.1 | 2 | 0
18752 | 151 | 35 | 30.5 | 2 | 0
18753 | 151 | 35 | 15.5 | 2 | 0
18754 | 151 | 35 | 12.8 | 2 | 0
18643 | 151 | 35 | 4.25 | 2 | 0
18644 | 151 | 35 | 22.15 | 2 | 0
18645 | 151 | 35 | 7.45 | 2 | 0
18646 | 151 | 35 | 7.5 | 2 | 0
18751 | 151 | 34 | 25.34 | 5 | 0
18752 | 151 | 34 | 30.54 | 5 | 0
18753 | 151 | 34 | 15.48 | 5 | 0
18754 | 151 | 34 | 13.08 | 5 | 0
18643 | 151 | 34 | 4.3 | 5 | 0
18644 | 151 | 34 | 22.44 | 5 | 0
18645 | 151 | 34 | 7.34 | 5 | 0
18646 | 151 | 34 | 7.54 | 5 | 0
您可以使用以下方法获取最近的行:
select t.*
from temperatures t
order by abs(temperature_value - ACTUAL_TEMPERATURE) asc
limit 2
或者,在这种情况下更好的想法是 union
:
(select t.*
from temperatures t
where temperature_value <= ACTUAL_TEMPERATURE
order by temperature_value desc
limit 1
) union
(select t.*
from temperatures t
where temperature_value >= ACTUAL_TEMPERATURE
order by temperature_value asc
limit 1
)
这个版本更好,因为如果温度在 table,它 returns 只有一行。在这种情况下,UNION
和重复删除很有用。
接下来使用条件聚合来获取所需的信息。这里使用了一个捷径,假设kw随温度增加:
select min(temperature_value) as mintv, max(temperature_value) as maxtv,
min(temperature_current_kw) as minck, max(temperature_current_kw) as maxck
from ((select t.*
from temperatures t
where temperature_value <= ACTUAL_TEMPERATURE
order by temperature_value desc
limit 1
) union
(select t.*
from temperatures t
where temperature_value >= ACTUAL_TEMPERATURE
order by temperature_value asc
limit 1
)
) t;
最后,做一些算术运算得到加权平均值:
select (case when maxtv = mintv then minkw
else minkw + (ACTUAL_TEMPERATURE - mintv) * ((maxkw - minkw) / (maxtv - mintv))
end)
from (select min(temperature_value) as mintv, max(temperature_value) as maxtv,
min(temperature_current_kw) as minkw, max(temperature_current_kw) as maxkw
from ((select t.*
from temperatures t
where temperature_value <= ACTUAL_TEMPERATURE
order by temperature_value desc
limit 1
) union
(select t.*
from temperatures t
where temperature_value >= ACTUAL_TEMPERATURE
order by temperature_value asc
limit 1
)
) t
) t;
如果我有一个 table 在特定温度下保持 运行 平均 kW 使用量,并且我想获得之前未记录的温度的 kW 使用量,如何我可以得到
(A) 高于或低于温度的两个数据点进行推断。
(B) 要插入的高于和低于温度的最接近数据
table温度看起来像这样
Column | Type | Modifiers | Storage | Stats target | Description
-------------------------+------------------+-----------+---------+--------------+---------------
temperature_io_id | integer | not null | plain | |
temperature_station_id | integer | not null | plain | |
temperature_value | integer | not null | plain | | in Fahrenheit
temperature_current_kw | double precision | not null | plain | |
temperature_value_added | integer | default 1 | plain | |
temperature_kw_year_1 | double precision | default 0 | plain | |
"temperatures_pkey" PRIMARY KEY, btree (temperature_io_id, temperature_station_id, temperature_value)
(A) 建议的解决方案
我想这会更容易一些。查询将按温度值 >
或 <
我想要的温度对行进行排序,然后将结果限制为 2?这将给我高于或低于温度的两个最接近的值。当然,顺序必须是降序和升序,以确保我得到正确的项目。
SELECT * FROM temperatures
WHERE
temperature_value > ACTUALTEMP and temperature_io_id = ACTUAL_IO_id
ORDER BY
temperature_value
LIMIT 2;
我认为与上面类似,但只限制为 1 并执行 2 个查询,一个用于 >
,另一个用于 <
。不过我觉得这可以做得更好?
编辑 - 一些示例数据
temperature_io_id | temperature_station_id | temperature_value | temperature_current_kw | temperature_value_added | temperature_kw_year_1
-------------------+------------------------+-------------------+------------------------+-------------------------+-----------------------
18751 | 151 | 35 | 26.1 | 2 | 0
18752 | 151 | 35 | 30.5 | 2 | 0
18753 | 151 | 35 | 15.5 | 2 | 0
18754 | 151 | 35 | 12.8 | 2 | 0
18643 | 151 | 35 | 4.25 | 2 | 0
18644 | 151 | 35 | 22.15 | 2 | 0
18645 | 151 | 35 | 7.45 | 2 | 0
18646 | 151 | 35 | 7.5 | 2 | 0
18751 | 151 | 34 | 25.34 | 5 | 0
18752 | 151 | 34 | 30.54 | 5 | 0
18753 | 151 | 34 | 15.48 | 5 | 0
18754 | 151 | 34 | 13.08 | 5 | 0
18643 | 151 | 34 | 4.3 | 5 | 0
18644 | 151 | 34 | 22.44 | 5 | 0
18645 | 151 | 34 | 7.34 | 5 | 0
18646 | 151 | 34 | 7.54 | 5 | 0
您可以使用以下方法获取最近的行:
select t.*
from temperatures t
order by abs(temperature_value - ACTUAL_TEMPERATURE) asc
limit 2
或者,在这种情况下更好的想法是 union
:
(select t.*
from temperatures t
where temperature_value <= ACTUAL_TEMPERATURE
order by temperature_value desc
limit 1
) union
(select t.*
from temperatures t
where temperature_value >= ACTUAL_TEMPERATURE
order by temperature_value asc
limit 1
)
这个版本更好,因为如果温度在 table,它 returns 只有一行。在这种情况下,UNION
和重复删除很有用。
接下来使用条件聚合来获取所需的信息。这里使用了一个捷径,假设kw随温度增加:
select min(temperature_value) as mintv, max(temperature_value) as maxtv,
min(temperature_current_kw) as minck, max(temperature_current_kw) as maxck
from ((select t.*
from temperatures t
where temperature_value <= ACTUAL_TEMPERATURE
order by temperature_value desc
limit 1
) union
(select t.*
from temperatures t
where temperature_value >= ACTUAL_TEMPERATURE
order by temperature_value asc
limit 1
)
) t;
最后,做一些算术运算得到加权平均值:
select (case when maxtv = mintv then minkw
else minkw + (ACTUAL_TEMPERATURE - mintv) * ((maxkw - minkw) / (maxtv - mintv))
end)
from (select min(temperature_value) as mintv, max(temperature_value) as maxtv,
min(temperature_current_kw) as minkw, max(temperature_current_kw) as maxkw
from ((select t.*
from temperatures t
where temperature_value <= ACTUAL_TEMPERATURE
order by temperature_value desc
limit 1
) union
(select t.*
from temperatures t
where temperature_value >= ACTUAL_TEMPERATURE
order by temperature_value asc
limit 1
)
) t
) t;