2016-09-06 16 views
0

私はappsテーブルを持っています。各アプリには多くのconversationsusersがあります。会話にはmessagesが多く、各メッセージはvisitorまたはuserに属し、visitorには多くの会話を持つことができます。クエリで重複する結果

私の会話ごとに、会話に最後に書き込んだユーザーの名前とアバターを添付したいと思います。

ユーザーが返信していない場合は、最も最近作成された3人のユーザーのavatarsをアプリ名と共に取得し、代わりに使用したいと考えています。

これは私がこれまで持っているものですが、すべてのヘルプは非常にあるそれは同じ対話idのための複数の結果を返す、と私は見つかっていないアプリのユーザーを取得するソリューションは

select 
     c.id, 
     c.last_message, 
     c.last_activity, 
     coalesce(last.display_name, a.name || ' Team') as name, 
     array_agg(last.avatar) 
     from messages m 
     left join conversations c on c.id = m.conversation_id 
     left join apps a on a.id = c.app_id 
     left join lateral (
      select u.id, u.display_name, u.avatar 
      from users u 
      where u.id = m.user_id 
    ) as last on true 
     where c.visitor_id = 'c6p77hu9v000a4zcth4lnefn9' 
     group by c.id, last.display_name, last.avatar, a.name 
     order by c.inserted_at desc 

をアバター

+0

これが解決すればわかりません。最近返信されたとは、その特定の会話の最後に挿入された行を取得することを意味します。その会話にMIN/MAX()を使ってみましたか?テーブル構造とサンプル出力を表示する方が良いでしょう。 –

+0

希望の出力内でサンプルデータを入力すれば、私は助けることができます:) – kbball

答えて

1

私の会話ごとに、会話に最後に書き込んだユーザーの名前とアバターを添付したいと思います。

はそれを行うには、LATERALサブクエリを使用することができますが、あなたはまた、その後、最後のメッセージが最初になるようにORDER BYを追加するだけで、最後の行を取得するためにLIMIT 1を使用する必要があります。私は仮定のであれば、あなたはメッセージが送信された日付と時刻を格納しmessage表の列message_datetimeを、持っている、あなたが使用することができます。どのユーザーが回答していない場合

select 
     c.id, 
     c.last_message, 
     c.last_activity, 
     coalesce(last.display_name, a.name || ' Team') as name, 
     last.avatar 
from 
    conversations c 
    left join apps a on a.id = c.app_id 
    left join lateral (
     select 
      u.id, u.display_name, u.avatar 
     from 
      users u 
      inner join messages m on u.id = m.user_id 
     where 
      c.id = m.conversation_id 
     order by 
      m.message_datetime desc 
     limit 1 
    ) as last on true 
where 
    c.visitor_id = 'c6p77hu9v000a4zcth4lnefn9' 
order by 
    c.inserted_at desc 

、その後、代わりに私は思います最近作成された3人のユーザーのアバターをアプリケーションの名前と共に取得し、代わりに使用するようにします。

これは以前のクエリとは無関係ですが、これは簡単です。

select 
    u.id, u.display_name, u.avatar 
from 
    users u 
order by 
    u.created_datetime desc 
limit 3 

だからあなたがコントロールするCOALESCEを使用して、前のクエリでサブクエリとして使用することができます:あなたのusersは、日付と時刻、ユーザが作成されているとcreated_datetime列を持っている、あなたは単純なクエリを使用することができますと仮定すると、どの情報を使用する:

select 
     c.id, 
     c.last_message, 
     c.last_activity, 
     coalesce(last.display_name, a.name || ' Team') as name, 
     coalesce(array[last.avatar], last_all.avatar) as avatar 
from 
    conversations c 
    left join apps a on a.id = c.app_id 
    left join lateral (
     select 
      u.id, u.display_name, u.avatar 
     from 
      users u 
      inner join messages m on u.id = m.user_id 
     where 
      c.id = m.conversation_id 
     order by 
      m.message_datetime desc 
     limit 1 
    ) as last on true 
    left join (
     select 
      array_agg(u.avatar) as avatar 
     from 
      users u 
     order by 
      u.created_datetime desc 
     limit 3 
    ) last_all on true 
where 
    c.visitor_id = 'c6p77hu9v000a4zcth4lnefn9' 
order by 
    c.inserted_at desc 
+0

これは完璧です、ありがとう – Tarlen

関連する問題