2

くだらないタイトルでごめんなさい。例を挙げて説明します。

いいねテーブルがあり、各いいねのエントリがあるとします

user_id  |  liked_id
--------------------
   1     |     a
   2     |     a
   1     |     b
   2     |     c

1ユーザーがアイテムaとを気に入りb、ユーザー2がアイテムaとを気に入ったことを意味しますc

各アイテムのいいねの総数を取得するには、次のようにします。

SELECT liked_id, COUNT(*)
  FROM likes
  GROUP BY liked_id

ただし、特定のユーザーが気に入ったアイテムのみを対象とする良い方法はありますか? したがって、たとえば、 user に対してクエリを実行する1と、次のような結果が得られます。

liked_id |  count
------------------
   a     |    2
   b     |    1

ユーザー1がアイテムaとを気に入ったが、 を気に入らbなかったためcです。

私が考えることができる最善の方法は、JOINまたはINサブセレクトを使用することです。

SELECT l.liked_id, count(*)
  FROM likes l
    JOIN (
      SELECT liked_id
        FROM likes
        WHERE user_id = 1
      ) l2
      ON l.liked_id=l2.liked_id
  GROUP BY l.liked_id;

集約するときに物事をまとめるより良い方法はありますか? できるトリックがあるHAVINGかもしれないと思いますが、そうではないかもしれませんし、とにかく遅い解決策かもしれません.

EDIT:タグがそれを明確にしなかった場合、私はPostgresを使用しています。

編集:すべての回答に感謝します。質問をしたときに、私が最善かつ最速だと思ったものを受け入れました-明らかにすべきだったのですが、全員に+1を付けました。

後で注文できるように、likes テーブルのエントリから別のデータが必要であることを言及する必要がありました。SELECTサブセレクトは、受け入れられた回答がandの部分に追加のエントリと結合するのと同様にそれを行いGROUP BYます。SOの質問のために何かを単純化しすぎることを教えてくれます...ありがとう!

4

4 に答える 4

2

次のようなものを試すことができます:

SELECT liked_id, COUNT(*)
  FROM likes
 GROUP BY liked_id
HAVING count(case when user_id = 1 then 1 end) > 0;

count(case when user_id = 1 then 1 end)user_id = 1特定の「いいね!」の回数をカウントしますliked_id

このクエリは、1 回のフル スキャンで結果を取得します。2 回のフル スキャンよりも高速ですが、2 回のインデックス スキャンよりも遅くなる可能性があります ( と にインデックスがある場合liked_id) user_id

于 2013-08-13T17:55:05.797 に答える
1

私の理解によれば、これは機能するはずですcount。特定の人だけが気に入ったお気に入りのアイテムを取得する必要がありますuser

SELECT 
  liked_id, 
  COUNT(*)
FROM 
  likes l
WHERE
  EXISTS ( SELECT 1 FROM likes WHERE user_id = 1 AND like_id = l.id )
GROUP BY 
  liked_id
于 2013-08-13T17:55:13.010 に答える