Tôi có một bảng chứa hai cột hoán vị / kết hợp các mảng số nguyên và cột thứ ba chứa một giá trị, như vậy:
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' )
Tôi muốn tìm ra độ lệch trung bình và độ lệch chuẩn cho mỗi hoán vị, cũng như cho mỗi kết hợp. Tôi có thể làm điều đó với truy vấn này:
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 );
Tuy nhiên, truy vấn đó có thể trở nên khá chậm khi tôi có nhiều dữ liệu, bởi vì bảng "foo" (trong thực tế, bao gồm 14 phân vùng, mỗi phân vùng có khoảng 4 triệu hàng) cần được quét hai lần.
Gần đây, tôi được biết rằng Postgres hỗ trợ "Các hàm cửa sổ", về cơ bản giống như một NHÓM THEO cho một cột cụ thể. Tôi đã sửa đổi truy vấn của mình để sử dụng như vậy:
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 );
Trong khi điều này hoạt động cho cột "combo_count", các cột "combo_alusive_value" và "combo_stddev" không còn chính xác nữa. Có vẻ như trung bình đang được lấy cho mỗi hoán vị, và sau đó được tính trung bình lần thứ hai cho mỗi kết hợp, điều này là không chính xác.
Làm thế nào tôi có thể sửa lỗi này? Các chức năng cửa sổ thậm chí có thể được sử dụng như một tối ưu hóa ở đây?