2011-01-10 20 views
1

会話の最後のコメントをすべて選択しようとしています。同じobject_idとtype_idを持つ場合、コメントは同じ会話にあります。これは私が今行っている質問です:sqlクエリでグループを使用して問題が発生しました。

select * from comments 
where user_id != #{current_user.id} 
group by type_id, object_id 
order by created_at desc 

コメントは常に会話の最後ではないことを除いては機能します。どうやってやるの?私はそれがmysqlとsqlite3で動作する必要があります。

+0

コメントテーブルのスキーマを含めてください。 'type_id'とは何ですか?そして' object_id'は何ですか?また、どのORM(もしあれば)を使用していますか:ActiveRecord、Sequel、または生のSQLコマンドだけですか? – Phrogz

+0

与えられたsqlコマンドは、あなたが知る必要があるすべての情報を提供する必要があります – tybro0103

+0

この質問はRubyまたはRailsとどう関係していますか? – klew

答えて

0

ここでは推測していますが、具体的にはスキーマに関する情報が必要です。最後のコメントが必要ですか、最後に見つけようとしていますか?の "conversation"によると、のコメントはありますか?

SELECT * 
    FROM comments 
    WHERE user_id != ... 
ORDER BY type_id, 
     object_id, 
     created_at DESC 
+0

ちょうど最後の1 – tybro0103

+0

ありがとうございます。あなたの元の質問へのコメントの質問に答えてください。 – Phrogz

1

このクエリは非常にきれいな(自分のサーバー上で実行するために、おそらく非常に遅い)ではありませんが、...

SELECT 
    MAX(created_at) created_at, 
    * 
FROM 
    comments 
WHERE 
    user_id != #{current_user.id} 
GROUP BY 
    type_id, 
    object_id 
ORDER BY 
    created_at DESC 

編集:ただ、これは動作しません気づきました。必要なのは、これを解決するための表スキーマです。

1

GROUPに問題がある場合は、まず「*」を使用しないでください。これは、MySQLが提供するSQLの標準GROUP BYの拡張です。

クラシックグループbyは、selectで使用されるすべての非集約カラムを含む必要があります。 MySQLは非常に基本的な事実を避けることができましょうし、その結果にいくつかのランダム性を得る:

同様のMySQLの拡張が HAVING句に適用されます。 SQL標準 は、 集合関数に囲まれていない場合、GROUP BY句に見つからない列をHAVING句に という名前で名前付けすることを許可しません。 MySQLでは、 の計算を簡素化するために、このような列を で使用できます。 この拡張では、 と仮定すると、グループ化されていない列は同じグループ単位の値である になります。そうでない場合、 結果は不確定です

プレーンな選択でクエリの更新版を試してください。

0

GROUP BYクエリのみを使用して必要な結果を取得することはできません。その理由は、RDBMSにGROUPされたセットの最後のコメントに対応するコメントテキストを選択するよう指示する方法がないからです。

代わりにこれを実行します。(私はそれがコメントを識別するものは明らかではありませんので、comment_idを使用しますが、代わりにそれを使用し、その後OBJECT_IDの場合)

SELECT * FROM comments 
    WHERE user_id != #{current_user.id} AND created_at = 
    (SELECT MAX(created_at) FROM comments WHERE user_id != #{current_user.id}) 

または

SELECT * FROM comments c1 
    WHERE user_id != #{current_user.id} AND NOT EXISTS 
    (SELECT * FROM comments c2 
     WHERE user_id != #{current_user.id} AND c2.created_at > c1.created_at) 

を。

0

あなたはTYPE_IDとのobject_idの各グループ内の最後のコメントを選択したい場合は、サブクエリを使用します。

これはまったく同じTYPE_ID「のobject_idとのcreated_at値を有する複数のコメントがある以外作品
select c1.* 
from comments c1 
join (
    select type_id, object_id, max(created_at) last_comment_created_at 
    from comments 
    where user_id != #{current_user.id} /* indicates 'comment'? */ 
    group by type_id, object_id 
) c2 
on c2.type_id = c1.type_id 
    and c2.object_id = c1.object_id 
    and c2.last_comment_created_at = c1.created_at 

。したがって、 'comment_order'のような列がある場合は、 'created_at'よりも優先されます。

+0

created_atはタイムスタンプなので、問題ではありません – tybro0103

関連する問題