问题
I have two tables, which look like this (simplified):
Operations:
|operation_id|description|created_at|
|------------|-----------|----------|
| 1| abc|2020-04-04|
Transactions
|transaction_id|amount|created_at|user_id|operation_id|type|
|--------------|------|----------|-------|------------|----|
| 1| 400|2020-04-04| 1| 1| tr|
| 2| 400|2020-04-04| 2| 1| tr|
How can I find all operations in which transaction.user_id's intersects with an array of user ids? E.g. for array [1, 2] there will be match (operation_id = 1), because both ids were in transaction.user_id for that operation. For array [1, 3] there will be no matches because it only partially matches transaction.user_id that belongs to a specific operation.
回答1:
You can aggregate the user_ids and then compare them with your array:
select o.*
from operations o
join (
select operation_id, array_agg(user_id order by user_id) as user_ids
from transactions t
group by operation_id
) t on t.operation_id = o.operation_id and user_ids = array[1,2];
Alternatively you could use an IN condition:
select o.*
from operations o
where operation_id in (select operation_id
from transactions t
group by operation_id
having array_agg(user_id order by user_id) = array[1,2]);
The order by user_id in the array_agg() call is important because equality of arrays depends on the order of elements. array[1,2] is not equal to array[2,1]
So you need to make sure that the user IDs in the array used for the join condition are also sorted properly.
来源:https://stackoverflow.com/questions/63484304/filter-parent-by-it-child-ids