2017-03-28 2 views
1

テーブルがあります。ユーザーのために通知を返すと、number_of_likes、number_of_comments、およびliked_by_meという列も作成されます。クエリを作成するユーザーが通知を気に入らなかった場合、クエリは正常に動作しています(liked_by_me = 0)。しかし、彼らが(liked_by_me = 1)を持っていれば、number_of_likesの値は間違っていて、number_of_commentsと同じです。SQLクエリは、別の列のデータを含む列を返します。

例:

1)
- 私が気に入っ= falseを
は - = 1
が好き - = 5

コメント

戻り値:
- liked_by_me = 0
- number_of_likes = 1
- number_of_comments = 5

2)
- 真
=私が言っていますが - = 2
が好き - コメント= 5

戻り値:
- liked_by_me = 1
- number_of_likes = 5
- ここNUMBER_OF_COMMENTS = 5

私が使用しているクエリです:

SELECT notices.* 
    , count(comment.id) as number_of_comments 
    , count(like1.user_id) as number_of_likes 
    , like2.user_id IS NOT NULL AS liked_by_me 
    , boards.name as board_name 
FROM notices 
LEFT JOIN comments as comment 
    ON (comment.notice_id = notices.id) 
LEFT JOIN likes as like1 
    ON (like1.notice_id = notices.id) 
LEFT JOIN likes as like2 
    ON (like2.notice_id = notices.id 
    AND like2.user_id = $1) 
LEFT JOIN boards 
    ON (boards.id = notices.board_id) 
LEFT OUTER JOIN board_users 
    ON (board_users.board_id = notices.board_id) 
WHERE board_users.user_id = $1 
GROUP BY notices.id 
     , boards.name 
     , like2.user_id 
     , userId 

preciated。私はこれを何時間も続けてきたが、問題を見つけることはできないと思う。

ありがとうございます!

ソリューション: ここでの作業クエリ

SELECT notices.*, 
(SELECT COUNT(user_id) from likes WHERE likes.notice_id = notices.id) AS number_of_likes, 
(SELECT user_id IS NOT NULL from likes WHERE likes.notice_id = notices.id AND likes.user_id = $1) AS liked_by_me, 
count(comments.id) as number_of_comments, boards.name as board_name 
FROM notices LEFT JOIN comments ON (comments.notice_id = notices.id) 
LEFT JOIN boards ON (boards.id = notices.board_id) 
LEFT OUTER JOIN board_users ON (board_users.board_id = notices.board_id) 
WHERE board_users.user_id = $1 GROUP BY notices.id, boards.name", user); 

答えて

0

はあなたがsubeselectsを使用する必要がありますです。この問題の

優秀な記事:The GROUPing pitfall

TL; DR:基本的には、すべてのあなたの意見や好みがお互いにより増倍されていることを、理解しなければなりません。グループ句を付けずにクエリの結果を表示して、重複している好き/コメントを数えていることを確認してください。

編集:私はこれをテストしていないが、それは、クエリがどのように見えるかです:

SELECT 
    notices.*, 
    comments.number_of_comments, 
    likes.number_of_likes 
    current_user_likes.user_id IS NOT NULL AS liked_by_me 
    boards.name AS board_name 
FROM notices 

LEFT JOIN (
    SELECT 
     COUNT(*) AS number_of_comments, 
     notice_id 
    FROM comments 
    GROUP BY notice_id 
) AS comments ON comments.notice_id = notices.id 

LEFT JOIN (
    SELECT 
     COUNT(*) AS number_of_likes, 
     notice_id 
    FROM likes 
    GROUP BY notice_id 
) AS likes ON likes.notice_id = notices.id 

LEFT JOIN likes AS current_user_likes 
    ON current_user_likes.notice_id = notices.id 
     AND current_user_likes.user_id = $1 
LEFT JOIN boards ON boards.id = notices.board_id 

INNER JOIN board_users 
    ON board_users.board_id = notices.board_id 
     AND board_users.user_id = $1; 
(ユーザーが一つだけの通知のように一度、そうでなければ、現在のユーザーがあまりにも好きなグループになければならないことができれば、それはあります)
+0

ありがとうございました!あなたのアドバイスは本当に私がそれを理解するのを助けました。だから私はJOINsでsubselectsを使用しようとしましたが、彼らはまだグループ化を必要とし、結託フィールドはまだ間違った値を返していました。私は最後に、クエリの列宣言に副選択を追加することによって正しい値を得ることができました。 –

+0

私はSQLクエリとしての意味を付け加えました。テストされていませんが、それは私が気にしていたものです。私は列のクエリの副選択肢がどのようにパフォーマンスが良いかわかりません。 – PunchyRascal