如何获取在 WHERE id IN 字段中找到的聚合结果?

问题描述 投票:0回答:1

我需要获取每笔交易中的

transactions
列表以及
logs
tags
列表,并且最重要的是按
logs
tags
中的字段进行搜索并将其统一起来。 以下示例是通过
field1
tag1
进行搜索。怎么做?同样重要的是:我有 500m+ 行。如果使用
WHERE id IN ..
会很慢吗?

transactions
 id int
 hash var

id | hash 
------------
1  |  h1
2  |  h2
3  |  h3
logs
 transaction_id int
 field1 var
 value var

transaction_id | field1 | value 
-------------------------------
1              | f1     | v1
1              | f2     | v2
2              | f3     | v3
3              | f4     | v4
tags
 transaction_id int
 tag1 var
 value var

transaction_id | tag1   | value 
-------------------------------
1              | t1     | v1
2              | t2     | v2
2              | t3     | v3

我需要结果:

id | hash | logs_array                                                         | tags_array
------------------------------------------------------------------------------------------
1  | h1   | [{'field1': 'f1', 'value': 'v1'}, {'field1': 'f2', 'value': 'v2'}] | [{'tag1': 't1', 'value': 'v1'}]
2  | h2   | [{'field1': 'f3', 'value': 'v3'}]                                  | [{'tag1': 't2', 'value': 'v2'}, {'tag1': 't3', 'value': 'v3'}]
3  | h3   | [{'field1': 'f4', 'value': 'v4'}]                                  | []

我能想到的示例模板:

SELECT t.id, t.hash, array_agg(..) FROM transactions t WHERE id in
    (
        SELECT transaction_id FROM logs WHERE field1={any_string}
    )
    OR id in
    (
        SELECT transaction_id FROM tags WHERE tag1={any_string}
    )
LEFT JOIN logs lo ON t.id = lo.transaction_id
LEFT JOIN tags ta ON t.id = ta.transaction_id
sql postgresql group-by left-join
1个回答
0
投票

这可以通过这样的查询来完成

select t.id, t.hash, 
array_agg (distinct jsonb_build_object('field1', l.field1, 'value', l."value")) logs_array,
array_agg (distinct jsonb_build_object('tag1', tg.tag1, 'value', tg."value")) tags_array
from transactions t 
left join logs l on t.id = l.transaction_id 
left join tags tg on t.id = tg.transaction_id
group by t.id, t.hash 
order by t.hash;

拨弄测试

© www.soinside.com 2019 - 2024. All rights reserved.