2017-02-08 2 views
0

ユーザー表あたり制限行MYSQL:前記()

ID


user_comments表

ID | user_id |コンテンツ|


のcreated_at私は、ユーザーIDのリストを持っている、と私は、ユーザーIDごとの最新の3件のコメントをつかむしたいです。

SELECT * FROM user_comments WHERE user_id IN (1, 2, 3, 4, 5) 
ORDER BY created_at DESC 
LIMIT 3; 

これは、すべての一致するIDが、私は IDの最後の3件のコメントをしたいから最後の3件のコメントをつかむだろう。 1つのクエリは、ユニオンを使用しないことが好ましい

私は右自体にテーブルに参加しようとしているが、私はそれが権利を取得するように見える傾けます。

** 編集:私は発注のためのidカラムに頼ることができない、それは日付列を使用する必要があります。

ありがとうございました。


** 私の最終解決

SELECT user_comments.* FROM user_comments 
LEFT OUTER JOIN user_comments user_comments_2 
ON user_comments.post_id = user_comments_2.post_id 
    AND user_comments.id < user_comments_2.id  
where user_comments.post_id in (x,x,x) 
GROUP BY user_comments.id 
HAVING COUNT(*) < 3 
ORDER BY user_id, created_at 

@PaulSpiegelによって提案された答えは(警告を)私のために仕事をした、しかし、私は上記の一緒に行くことになった私が使用して作られたソリューションに参加このスレッドからの情報:ビルKarwin言及link

ありがとうございました!

+0

SELECT * FROM user_id = 1またはuser_id = 2またはuser_id = 3またはuser_id = 4 ORDER BY created_at DESC LIMIT 3; –

+0

AUTO_INCREMENT列はありますか? –

+0

@PaulSpiegel - はい、id列はauto_incです。 – magnito

答えて

2

created_atの代わりにidを使用できる場合は、idと3番目に高いidのユーザーを比較できます。あなたはどちらLIMIT 1 OFFSET 2とサブクエリで見つけることができます。ユーザが3つの未満コメントはid >= 0持つすべてのコメントを選択するために、COALESCE(またはIFNULL)を使用した場合について。

SELECT * 
FROM user_comments c 
WHERE user_id IN (1, 2, 3, 4, 5) 
    AND id >= COALESCE((
    SELECT id 
    FROM user_comments c1 
    WHERE c1.user_id = c.user_id 
    ORDER BY id DESC 
    LIMIT 1 
    OFFSET 2 
), 0) 
ORDER BY user_id, id DESC 

あなたが注文するためのidを使用できない場合は... 3番目と4番目のコメントは、同じタイムスタンプを持っている場合は、その後、(そうが)、3件の以上のコメントを取得する可能性があります

SELECT * 
FROM user_comments c 
WHERE user_id IN (1, 2, 3, 4, 5) 
    AND created_at >= COALESCE((
    SELECT created_at 
    FROM user_comments c1 
    WHERE c1.user_id = c.user_id 
    ORDER BY created_at DESC 
    LIMIT 1 
    OFFSET 2 
), '1970-01-01 00:00:00') 
ORDER BY user_id, created_at DESC 

注意。

+0

申し訳ありませんが、私のアプリケーションでは草稿として保存して後で公開することができるので、コメントの順序についてはid列に頼ることができません。 – magnito

+0

@magnitoそれはタイムスタンプを使っても動作しますが、ノートを読んでください。サブクエリに欠落しているORDER BY句も追加しました。 –

+0

BillKarwinが言及したスレッドで提案されている結合ソリューションを使いこなすことになりました。それは、重複した日付で同じ問題を抱えていないし、より速い(私の状況で)。 – magnito

1

する

select * 
from (
    select *, 
     @currentRank := if(@prevId = user_id, @currentRank, 0) + 1 as rank, 
     @prevId := user_id 
    from user_comments 
    order by user_id, created_at desc) as user_comments 
where rank <= 3 
を試してみて内側のクエリは、行から行に値を変更し、変数 @ SQLを使用しています。特定のユーザーのコメントがあるためorder by user_idのグループ化されます。 @currentRank変数は特定のグループの行のランクを格納します。 @currentRankは、新しいグループの開始時にゼロになります。

user_commentsテーブルの各レコードに対して1回だけ反復処理を行うにはRDMSが必要であるため、結果は最適化されません。ただし、外側のwhere句はその後に実行されます。