2016-09-12 8 views
1

データベースから会話のリストを取得しようとしていますが、最新のメッセージを表示したいのですが。私はそれを行うことができる(そしてN + 1ではない)クエリを見つけるのが難しいです。関連集約列に基づいて、グループの非集約列を選択してください。

私は、これらのテーブルがあります。

chats(id, user_id, post_id, created_at) 
messages(id, user_id, chat_id, body, created_at) 

を私は心の中でこのようなクエリた:

select chats.id, chats.user_id, m.latest from chats 
inner join (
    select chat_id, max(created_at) as latest from messages 
    group by chat_id 
) as m on m.chat_id = chats.id; 

をしかし、私はmax(created_at)結果に対応する行からメッセージボディを追加したいです。そのような関連する列を取得することは可能ですか?

答えて

3

(鷺の回答を参照してください)。 Postgresので

は、独自distinct on()は、窓関数を用いて、同等の溶液よりも、多くの場合、高速である:窓関数を用い

select chats.id, chats.user_id, m.body, m.latest 
from chats 
    join (
    select distinct on (chat_id) chat_id, body, created_at as latest 
    from messages 
    order by chat_id, created_at desc; 
) as m on m.chat_id = chats.id; 

溶液はしかし、より柔軟です。最新の2つ(または3つまたは...)のメッセージを受け取ることもできますが、distinct on()は1つのみを取得します。

+0

これは私の使用には完璧です、ありがとう –

2

ROW_NUMBER()を使用してみてください:これはウィンドウ関数を使用して行うことができ、標準のSQLで

select chats.id, chats.user_id, m.body from chats 
inner join (
    select chat_id,body , 
      row_number() OVER(PARTITION BY chat_id ORDER BY created_at DESC) as rnk 
    from messages 
) m on m.chat_id = chats.id and m.rnk = 1; 
+0

興味深いことに、私は窓関数について知らなかった –

関連する問題