Reputation: 488
I have the following table with three columns:
id | type | value
-----+------+-------
foo | bar | 123
foo | bar | 456
foo | biz | 789
foo | biz | 987
baz | bar | 555
quz | biz | 777
I'm trying to aggregate value
across a given type
, returning a result like this:
id | bar | biz
-----+---------------+-----------
foo | {123,456} | {789,987}
baz | {555} | {}
quz | {} | {777}
What I've tried so far is self joining the table against itself twice (using LEFT JOIN
to account for empty columns) and then doing a DISTINCT
to remove duplicates prior to aggregation. Is there a better way?
Current query:
SELECT
test.id,
ARRAY_REMOVE(ARRAY_AGG(DISTINCT(t1.value)), NULL) AS bar,
ARRAY_REMOVE(ARRAY_AGG(DISTINCT(t2.value)), NULL) AS biz
FROM test
LEFT JOIN test t1 ON test.id = t1.id AND t1.type = 'bar'
LEFT JOIN test t2 ON test.id = t2.id AND t2.type = 'biz'
GROUP BY test.id;
Upvotes: 0
Views: 25
Reputation: 36087
Try:
SELECT id,
ARRAY_REMOVE( Array_agg( bar ), NULL ) as bbar,
ARRAY_REMOVE( Array_agg( biz ), NULL ) as bbiz
FROM (
SELECT id,
CASE WHEN type = 'bar' THEN value ELSE NULL END AS bar,
CASE WHEN type = 'biz' THEN value ELSE NULL END AS biz
FROM test
) x
GROUP BY id
Upvotes: 1