ฉันมีตารางที่มีสองคอลัมน์ของพีชคณิต / การรวมกันของอาร์เรย์จำนวนเต็มและคอลัมน์ที่สามที่มีค่าเช่น:
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' )
ฉันต้องการหาค่าเฉลี่ยและส่วนเบี่ยงเบนมาตรฐานสำหรับการเปลี่ยนแปลงแต่ละครั้งรวมถึงแต่ละชุดค่าผสม ฉันสามารถทำได้ด้วยแบบสอบถามนี้:
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 );
อย่างไรก็ตามการสืบค้นนั้นช้าลงมากเมื่อฉันมีข้อมูลจำนวนมากเนื่องจากตาราง "foo" (ซึ่งในความเป็นจริงประกอบด้วย 14 พาร์ติชั่นแต่ละอันมีประมาณ 4 ล้านแถว) ต้องสแกนสองครั้ง
เมื่อเร็ว ๆ นี้ฉันได้เรียนรู้ว่า Postgres รองรับ "ฟังก์ชั่นของหน้าต่าง" ซึ่งโดยทั่วไปแล้วจะเหมือนกับ GROUP BY สำหรับคอลัมน์ใดคอลัมน์หนึ่ง ฉันแก้ไขข้อความค้นหาเพื่อใช้สิ่งเหล่านี้:
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 );
แม้ว่าสิ่งนี้จะใช้ได้กับคอลัมน์ "combo_count" แต่คอลัมน์ "combo_average_value" และ "combo_stddev" นั้นไม่ถูกต้องอีกต่อไป ปรากฏว่ามีการใช้ค่าเฉลี่ยสำหรับการเปลี่ยนแปลงแต่ละครั้งและจากนั้นเฉลี่ยเป็นครั้งที่สองสำหรับแต่ละชุดค่าซึ่งไม่ถูกต้อง
ฉันจะแก้ไขสิ่งนี้ได้อย่างไร สามารถใช้ฟังก์ชั่นหน้าต่างเพื่อเพิ่มประสิทธิภาพได้ที่นี่หรือไม่