要插入/外推的SQL数据

时间:2016-02-05 21:26:21

标签: sql postgresql postgresql-9.5

如果我有一张能在某个温度下保持平均每千瓦使用量的表,并且我想获得以前没有记录的温度的千瓦使用量,我怎么能得到

(A)两个数据点高于或低于温度两点推断。

(B)最接近温度的最接近数据进行插值

温度看起来像这样

         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

1 个答案:

答案 0 :(得分:2)

您可以使用以下方式获取最近的行:

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
) 

这个版本更好,因为如果温度在表格中,它只返回一行。这种情况下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;