このクエリの私の目標は、communities
テーブルからすべてを取り出し、のjsonb
オブジェクトを結合から取り除くことです。入れ子配列内での並べ替えarray_aggクエリ
select communities.*,
(
select array_agg(jsonb_build_object('id', community_permissions.document_id))
from documents as conversations
join community_permissions on community_permissions.document_id = conversations.id
where conversations.published = true
and community_permissions.community_id = communities.id
) as conversations
from communities where communities.id = 110;
これはcommunities
の列のために、通常の列と行を返し、conversations
列で[{ id: 1 }, { id: 2 } ...]
ように見えるJSON配列:これはthuslyソートされていない場合には大丈夫動作します。すべてがうまくいきました。クエリがうまく機能し、SQLで宣言的に行とその重要な関係を一度に取得できます。私は別のテーブルからの結合で返された値をフィルタリングすることもできます(公開された会話だけがこのリストに返されます)。
私が今やりたいことは、ドキュメントテーブルの属性に基づいて会話を並べ替えることです(上記の会話のエイリアス)。単純なアプローチ:
select communities.*,
(
select array_agg(jsonb_build_object('id', community_permissions.document_id))
from documents as conversations
join community_permissions on community_permissions.document_id = conversations.id
where conversations.published = true
and community_permissions.community_id = communities.id
order by conversations.updated_at desc
) as conversations
from communities where communities.id = 110;
が動作しない - コラムウォーカーはconversations.updated_at値がGROUP_BY句であることを望んでいます。私はそうのような句でグループを追加する場合: - 私はエラー「式として使用サブクエリから返された複数の行を」取得
select communities.*,
(
select array_agg(jsonb_build_object('id', community_permissions.document_id))
from documents as conversations
join community_permissions on community_permissions.document_id = conversations.id
where conversations.published = true
and community_permissions.community_id = communities.id
group by conversations.updated_at
order by conversations.updated_at desc
) as conversations
from communities where communities.id = 110;
ARRAY_AGGは、もはや実際に応答を集約ように見えません。 order by
の後にlimit 1
を置くと、クエリが実行されますが、array_aggカラムで1つの会話しか取得できません。少なくとも最新のものです。だから、array_aggは配列に実際にはまっていないようです。私はCTE離れて全体を取って、使用して、このクエリを実行することができるよ
:
with q1 as (
select conversations.id as id, community_permissions.community_id as community_id
from documents as conversations
join community_permissions on community_permissions.document_id = conversations.id
where conversations.published = true order by conversations.updated_at desc
)
select communities.id, (
select array_agg(jsonb_build_object('id', q1.id))) as conversations
from communities join q1 on q1.community_id = communities.id
where communities.id = 110
group by communities.id;
が、それはかなり非効率的だが、説明する人は、それが全体の会話のテーブルにクエリを実行するたびにソートだことを示しています特定のコミュニティは、community_permissionsを介して共有されている会話テーブルの割合がわずかです。
私はクエリをモジュール化してバックエンドが "ちょっと、これらの値が必要になる"と判断し、それらをSQLクエリに押し込み、一度にすべてを一度に実行できるようにするために不満ですクエリを実行する代わりに、コミュニティをプルする代わりに、手動で各リレーションシップをクエリします(通常、コミュニティにはメンバー、会話、フォロワーなどがあります)。最悪の場合、私はこれを行うことができます - バックエンドノードのレイヤーで余分なフェッチを処理してそこにアセンブルしますが、サブクエリにすべて組み込むことは(このソート機能が必要になるまで)よりエレガントに見えます。