정수 배열의 순열 / 조합의 두 열과 값을 포함하는 세 번째 열을 포함하는 테이블이 있습니다.
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"테이블 (실제로 약 4 백만 개의 행이있는 14 개의 파티션으로 구성됨)을 두 번 스캔해야하므로 쿼리 속도가 느려질 수 있습니다.
최근에 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"열은 더 이상 정확하지 않습니다. 평균은 각 순열에 대해 취한 다음 각 조합에 대해 두 번째 평균화되는 것으로 보입니다 (잘못된).
이 문제를 어떻게 해결할 수 있습니까? 여기서 창 기능을 최적화로 사용할 수 있습니까?