I have a task that requires to sum ALL topup_val
performed by the id_user
that had at least one topup_val
ever by the amount of €15 exactly. This task needs to be solved in a single SELECT
statement, without any window functions or subqueries (nested SELECT
). I’m still a beginner in SQL so I found it struggle to finish this task.
I converted the topup_val
rows for each id_user
to array using array_agg()
. However, I cannot filter the array using WHERE
clause because WHERE
clause is performed before the aggregate function.
Thank you so much!
Table topups
id_user | topup_val ---------+----------- 1 | 10 1 | 15 1 | 5 2 | 10 2 | 10 3 | 15 3 | 15 3 | 10
Converted to array
id_user | topup_array ---------+------------------ 1 | {10, 15, 5} 2 | {10, 10} 3 | {15, 15, 10}
Expected result
id_user | topup_sum ---------+------------ 1 | 30 3 | 40
My PostgreSQL queries
SELECT id_user, array_agg(topup_val) AS array_topup FROM topups WHERE 15 = ANY(array_topup) GROUP BY id_user ORDER BY id_user;
Advertisement
Answer
Between group by and order by you can further filter your result set with HAVING
:
SELECT id_user,sum(topup_val) FROM topups GROUP BY id_user HAVING array_agg(topup_val) && array[15] ORDER BY id_user;
Demo: db<>fiddle
WITH topups (id_user,topup_val) AS ( VALUES (1,10),(1,15),(1,5),(2,10),(2,10),(3,15),(3,15),(3,10)) SELECT id_user, sum(topup_val) FROM topups GROUP BY id_user HAVING array_agg(topup_val) && array[15] ORDER BY id_user; id_user | sum ---------+----- 1 | 30 3 | 40 (2 rows)