Reputation: 1412
I'd like to display the contents of an array in one column and the size of an array in the next column. The array is generated off a subselect in my query. Is there a way I can reference the same array twice so I do not have to repeat the subselect query?
A simplified version of the query which works now is:
SELECT b.id,
(array_to_string(array
(
select currency_id
FROM RECORD
WHERE business_id = b.id
GROUP BY business_id,
currency_id), '|')) AS currencies,
array_length(ARRAY
(
SELECT currency_id
FROM RECORD
WHERE business_id = b.id
GROUP BY business_id,
currency_id), 1) AS num_currencies
FROM business b
from which I expect to get a result like:
id | currencies | num_currencies
-----+------------+----------------
53 | 38|36 | 2
235 | 36 | 1
289 | |
(3 rows)
Does the query planner see that it is the exact same subquery an optimize out running the second query or is there a better approach to getting this result?
Upvotes: 0
Views: 33
Reputation:
You don't need the sub-select twice. If you put your "main" query into a derived table, you can simply re-use the array
SELECT id,
array_to_string(currencies, '|') as currencies,
array_length(currencies, 1) as num_currencies
FROM (
SELECT b.id,
array(select currency_id
FROM record
WHERE business_id = b.id
GROUP BY business_id,
currency_id) AS currencies
FROM business b
) t;
Whether or not the optimizer detects the identical sub-queries should be visible from the execution plan.
But I think you can simplify this even more:
select b.id,
string_agg(r.currency_id::text, '|') as currencies,
count(*) as num_currencies
from business b
join record r on r.business_id = r.id
group by b.id
order by b.id;
Upvotes: 1