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;