Permütasyonlar / tamsayı dizileri kombinasyonları ve böyle bir değer içeren üçüncü bir sütun içeren bir tablo var:
CREATE TABLE foo
(
perm integer[] NOT NULL,
combo integer[] NOT NULL,
value numeric NOT NULL DEFAULT 0
);
INSERT INTO foo
VALUES
( '{3,1,2}', '{1,2,3}', '1.1400' ),
( '{3,1,2}', '{1,2,3}', '0' ),
( '{3,1,2}', '{1,2,3}', '1.2680' ),
( '{3,1,2}', '{1,2,3}', '0' ),
( '{3,1,2}', '{1,2,3}', '1.2680' ),
( '{3,1,2}', '{1,2,3}', '0' ),
( '{3,1,2}', '{1,2,3}', '0' ),
( '{3,1,2}', '{1,2,3}', '1.2680' ),
( '{3,1,2}', '{1,2,3}', '0.9280' ),
( '{3,1,2}', '{1,2,3}', '0' ),
( '{3,1,2}', '{1,2,3}', '1.2680' ),
( '{3,1,2}', '{1,2,3}', '0' ),
( '{3,1,2}', '{1,2,3}', '0' ),
( '{3,1,2}', '{1,2,3}', '1.2680' ),
( '{3,1,2}', '{1,2,3}', '0' ),
( '{3,2,1}', '{1,2,3}', '0' ),
( '{3,2,1}', '{1,2,3}', '0.8000' )
Her bir permütasyonun yanı sıra her kombinasyon için ortalama ve standart sapmayı bulmak istiyorum. Bu sorgu ile yapabilirim:
SELECT
f1.perm,
f2.combo,
f1.perm_average_value,
f2.combo_average_value,
f1.perm_stddev,
f2.combo_stddev,
f1.perm_count,
f2.combo_count
FROM
(
SELECT
perm,
combo,
avg( value ) AS perm_average_value,
stddev_pop( value ) AS perm_stddev,
count( * ) AS perm_count
FROM foo
GROUP BY perm, combo
) AS f1
JOIN
(
SELECT
combo,
avg( value ) AS combo_average_value,
stddev_pop( value ) AS combo_stddev,
count( * ) AS combo_count
FROM foo
GROUP BY combo
) AS f2 ON ( f1.combo = f2.combo );
Ancak, "foo" tablosu (gerçekte, her biri yaklaşık 4 milyon satırlı 14 bölümden oluşur) iki kez taranması gerektiğinden, bu sorgu çok fazla veri olduğunda oldukça yavaş olabilir.
Son zamanlarda, Postgres'in temelde belirli bir sütun için GROUP BY'a benzeyen "Pencere İşlevleri" ni desteklediğini öğrendim. Ben bu gibi kullanmak için benim sorgu değiştirildi:
SELECT
perm,
combo,
avg( value ) as perm_average_value,
avg( avg( value ) ) over w_combo AS combo_average_value,
stddev_pop( value ) as perm_stddev,
stddev_pop( avg( value ) ) over w_combo as combo_stddev,
count( * ) as perm_count,
sum( count( * ) ) over w_combo AS combo_count
FROM foo
GROUP BY perm, combo
WINDOW w_combo AS ( PARTITION BY combo );
Bu "combo_count" sütunu için çalışırken, "combo_average_value" ve "combo_stddev" sütunları artık doğru değildir. Her permütasyon için ortalamanın alındığı ve daha sonra her kombinasyon için ikinci bir kez ortalamanın alındığı anlaşılıyor, bu yanlış.
Bunu nasıl düzeltebilirim? Pencere fonksiyonları burada bir optimizasyon olarak kullanılabilir mi?