Filter parent by it child ids

与世无争的帅哥 提交于 2021-01-29 19:12:55

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!