Angenommen, wir haben die folgenden Tabellen:
create temporary table _data (ref_date date, value int);
insert into _data values
('2016-01-01', 34)
, ('2016-01-02', 12)
, ('2016-01-03', 25)
, ('2016-01-04', 17)
, ('2016-01-05', 22)
;
create temporary table _weight (days_in_past int, weight int);
insert into _weight values
(0, 4)
, (1, 2)
, (2, 1)
;
Wenn wir dann einen gleitenden Durchschnitt über ein Fenster von 3 Tage (einschließlich des aktuellen Datums) berechnet werden soll, wo Werte näher an dem aktuellen Datum sind ein höheres Gewicht als diejenigen, die weiter in der Vergangenheit zugewiesen, die wir für 2016-01-05
für den gewichteten Durchschnitt erwarten würden (basierend auf den Werten von 2016-01-05
, 2016-01-04
und 2016-01-03
):
(22*4 + 17*2 + 25*1)/(4+2+1) = 147/7 = 21
Und die Abfrage wie folgt aussehen könnte:
with _prepare_window as (
select
t1.ref_date
, datediff(day, t2.ref_date, t1.ref_date) as days_in_past
, t2.value * weight as weighted_value
, weight
, count(t2.ref_date) over(partition by t1.ref_date rows between unbounded preceding and unbounded following) as num_values_in_window
from
_data t1
left join
_data t2 on datediff(day, t2.ref_date, t1.ref_date) between 0 and 2
left join
_weight on datediff(day, t2.ref_date, t1.ref_date) = days_in_past
order by
t1.ref_date
, datediff(day, t2.ref_date, t1.ref_date)
)
select
ref_date
, round(sum(weighted_value)::float/sum(weight), 0) as weighted_average
from
_prepare_window
where
num_values_in_window = 3
group by
ref_date
order by
ref_date
;
Geben Sie das Ergebnis:
ref_date | weighted_average
------------+------------------
2016-01-03 | 23
2016-01-04 | 19
2016-01-05 | 21
(3 rows)
haben es geschafft, Sie mittlerweile eine Lösung zu finden? – thpl