2013-02-18 4 views
8

Angenommen, wir haben (in PostgreSQL 9.1) eine Tabelle mit einem Bezeichner, eine Spalte vom Typ integer [] und einige andere Spalten (mindestens eine, obwohl es möglicherweise mehr) vom Typ Integer (oder jede andere, die summiert werden kann).Array von verschiedenen Werten aggregiert von einer Array-Spalte in Postgres

Ziel ist es, ein Aggregat zu haben, das für jede Bezeichner-Summe die "summable" -Spalte und ein Array aller verschiedenen Elemente der Array-Spalte angibt.

Die einzige Möglichkeit, die ich finden kann, ist die Verwendung von unnest-Funktion für die Array-Spalte in einer Unterabfrage und dann mit einer anderen Unterabfrage zusammenzuführen, die die "summierbaren" Spalten aggregiert.

Ein einfaches Beispiel ist wie folgt:

CREATE TEMP TABLE a (id integer, aint integer[], summable_val integer); 
INSERT INTO a VALUES 
(1, array[1,2,3], 5), 
(2, array[2,3,4], 6), 
(3, array[3,4,5], 2), 
(1, array[7,8,9], 19); 

WITH u AS (
SELECT id, unnest(aint) as t FROM a GROUP BY 1,2 
), 
d AS (
SELECT id, array_agg(distinct t) ar FROM u GROUP BY 1), 
v as (
SELECT id, sum(summable_val) AS val 
FROM a GROUP BY 1 
) 
SELECT v.id, v.val, d.ar 
FROM v 
JOIN d 
ON v.id = d.id; 

Der obige Code ist, was ich gedacht, aber die Frage ist, können wir besser machen? Der Hauptnachteil dieser Lösung besteht darin, dass sie die Tabelle zweimal liest und aggregiert, was für größere Tabellen problematisch sein kann. Eine andere Lösung für das allgemeine Problem ist es, die Array-Spalte zu vermeiden und die "summierbare" Spalte für jedes Array-Element zu aggregieren und dann array_agg in Aggregation zu verwenden - aber zumindest möchte ich jetzt bei diesem Array-Weg bleiben .

Vielen Dank im Voraus für irgendwelche Ideen.

Antwort

6

Die Abfrage kann ein wenig schneller (nehme ich an), aber ich kann keine bemerkenswerte Optimierungen nicht sehen:

select a.id, sum(summable_val) val, ar 
from 
    (select id, array_agg(distinct t) ar 
     from 
     (select id, unnest(aint) as t from a group by 1,2) u 
    group by 1) x 
    join a on x.id = a.id 
group by 1,3 
Verwandte Themen