2011-09-10 7 views
0

BY GROUPとし、なしを選択:MySQLはテーブルを結合する私は、次の2つのテーブルを持っている

CREATE TABLE messages (
    messageId INT, 
    threadId INT, 
    recipientUserId INT, 
    message TEXT 
); 

CREATE TABLE thread_recipients (
    recipientUserId INT, 
    threadId INT 
); 

私はメッセージテーブルから各スレッドのSELECT特定のユーザーの最新のメッセージにしたいです。また、選択したスレッドの一部である他のすべてのユーザーをthread_recipientsテーブルから取得したいとします。

私は、次の動作だろうと思った:

SELECT MAX(m.messageId) AS maxMessageId, m.threadId, m.message 
    FROM messages AS m 
    RIGHT JOIN thread_recipients AS tr ON tr.threadId=m.threadId 
    WHERE m.recipientUserId='2' 
    GROUP BY m.threadId 

しかしながら、GROUP BYにしか関わらず、そのスレッドの一部であるユーザの数の、各スレッドIDのための一つの行を選択します。 1つのクエリで実行することも可能ですか?

どのレスポンダーにも親切です。 group by句なしで集約関数を呼び出すための

select max(messageId) over (partition by threadId) ... 

は非常に便利で、あなたのケースのために完璧にフィット:

+0

バックリンクはインラインコード用です。 [コードブロック](http://meta.stackexchange.com/questions/22186/how-do-i-format-my-code-blocks)では、行を4つ余分なスペースでインデントします。エディタツールバーの "{}"ボタンはこれを行います。書式設定の詳細とヒントについては、エディタツールバーのオレンジ色の疑問符をクリックしてください。テーブル構造はSQL文で表示する必要があります。あなたはSQLだけを求めているので、PHPコードの一部として投稿する必要はありません。 – outis

+2

'messages'と' thread_recipients'の 'recipientUserId'の違いは何ですか?彼らはどのように使われていますか? – outis

+0

私はあなたのスキーマがここに何であるのか分かりません。 – Bohemian

答えて

0

Oracleは、単に分析関数を使用してこれを解決します。

しかし、MYSQLでは、これを模倣するために内部セレクタを使用しますが、非常に大きなテーブルではメモリが重くなる可能性があることに注意してください。

SELECT mm.maxMessageId, m.threadId, m.message 
FROM messages AS m RIGHT JOIN thread_recipients AS tr ON tr.threadId=m.threadId, 
(
    select threadId, max(messageId) as maxMessageId 
    from messages group by threadId 
) AS mm 
WHERE m.recipientUserId=2 
    AND m.threadId = mm.threadId 
+0

'recipientUserId'はINTですので、暗黙の型キャスティングでは' 2'を単引用符に入れる必要はありません。インデックス) –

+0

あなたは正しいです、私はちょうど変更を強調するために彼の声明を変えないようにしておきました:) – edvaldig

+0

ありがとうございます@edvaldig ...私はあなたの答えを試してみましょう...だからあなたは何千万ものメッセージ?...私は本当にfacebookのような機能を備えたメッセージシステムを実現しようとしています...ありがとうございましたJ – jon

関連する問題