2.sql 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. do $$
  2. begin
  3. create table if not exists temperature_adjustments
  4. (
  5. id serial primary key,
  6. temperature numeric,
  7. adjustment numeric
  8. );
  9. if exists(select from temperature_adjustments limit 1) then
  10. raise notice 'Temperature_adjustments';
  11. else
  12. insert into temperature_adjustments(temperature, adjustment)
  13. values
  14. (0, 0), (5, 0.5), (10, 1), (15, 1), (20, 1.5), (25, 2), (30, 3.5), (40, 4.5);
  15. end if;
  16. if not exists(select from pg_type where typname = 'interpolation') then
  17. create type interpolation as (temperature_b numeric, temperature_t numeric, adjustment_b numeric, adjustment_t numeric, temperature numeric);
  18. end if;
  19. create or replace function calc_interpolation(temp1 numeric)
  20. returns interpolation
  21. language plpgsql as $func$
  22. declare interp interpolation;
  23. begin
  24. select temperature_b, temperature_t, adjustment_b, adjustment_t, temp1 as interpolation into interp from
  25. (select temperature as temperature_b, adjustment as adjustment_b from temperature_adjustments where temperature <= temp1 order by temperature desc limit 1)
  26. full join
  27. (select temperature as temperature_t, adjustment as adjustment_t from temperature_adjustments where temperature >= temp1 order by temperature limit 1)
  28. on true limit 1;
  29. if interp.temperature_b is null or interp.temperature_t is null then raise exception ':c'; end if;
  30. return interp;
  31. end;
  32. $func$;
  33. end $$;
  34. do $$
  35. begin
  36. create or replace function calc_adjustment(interp interpolation)
  37. returns numeric
  38. language plpgsql as $func$
  39. declare
  40. adjustment numeric;
  41. temp_min numeric;
  42. temp_max numeric;
  43. begin
  44. select min(temperature) from temperature_adjustments into temp_min;
  45. select max(temperature) from temperature_adjustments into temp_max;
  46. if interp.temperature <= temp_min or interp.temperature_b = interp.temperature or interp.temperature_t is null then
  47. select interp.adjustment_b into adjustment;
  48. elseif interp.temperature >= temp_max or interp.temperature_t = interp.temperature or interp.temperature_b is null then
  49. select interp.adjustment_t into adjustment;
  50. elseif interp.temperature_b = interp.temperature_t then
  51. select 0 into adjustment;
  52. else
  53. select interp.adjustment_b+((interp.temperature - interp.temperature_b) / (interp.temperature_t - interp.temperature_b)) * (interp.adjustment_t - interp.adjustment_b)
  54. into adjustment;
  55. end if;
  56. return adjustment;
  57. end;
  58. $func$;
  59. end $$;