2017-10-17 13 views
1

このクエリの私の目標は、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クエリに押し込み、一度にすべてを一度に実行できるようにするために不満ですクエリを実行する代わりに、コミュニティをプルする代わりに、手動で各リレーションシップをクエリします(通常、コミュニティにはメンバー、会話、フォロワーなどがあります)。最悪の場合、私はこれを行うことができます - バックエンドノードのレイヤーで余分なフェッチを処理してそこにアセンブルしますが、サブクエリにすべて組み込むことは(このソート機能が必要になるまで)よりエレガントに見えます。

答えて

1

集合関数で順序を指定できます。

試してみてください。

select communities.*, 
    (
    select array_agg(jsonb_build_object('id', community_permissions.document_id) order by conversations.updated_at desc) 
    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; 
1

これらのうちの1つは、「stackoverflowで長いポストを書き、10分後に答えを見つける」という状況です。

今後の参考として、間違った場所に注文しているということです。これは動作します:order byarray_agg呼び出しではなく、サブクエリの内側に今ある

select communities.*, 
    (
    select array_agg(jsonb_build_object('id', community_permissions.document_id) order by conversations.updated_at desc) 
    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; 

なお。

関連する問題