4

少し検索しましたが、達成しようとしているものとまったく同じものは見つかりませんでした。

基本的に、私は 2 人のユーザーの投票習慣の類似点を見つけようとしています。

私は、行われた個々の投票を格納するテーブルを持っています。

voteID
itemID     (the item the vote is attached to)
userID     (the user who voted)
direction  (whether the user voted the post up, or down)

たとえば、ユーザー A と B の間の類似性を計算するには、次の 2 つのことを調べます。

  1. 共通の票数。つまり、両者が同じ投稿に投票した回数です (この時点では方向は関係ありません)。
  2. 一般投票で同じ方向に投票した回数

(次に、大まかな類似性評価を達成するために、単純に #2 を #1 のパーセンテージとして計算します)。

私の質問は、どうすれば 2 人のユーザーの投票セットの交差を見つけることができるかということです。(つまり、非常に非効率的な方法ですべての投票をループすることなく、ポイント#1を適切に計算するにはどうすればよいですか。)それらが異なるテーブルにある場合、INNER JOINで十分だと思います...しかし、それは明らかに機能しません同じテーブルで(またはそうなるでしょうか?)。

どんなアイデアでも大歓迎です。

4

6 に答える 6

7

このようなもの:

SELECT COUNT(*)
FROM votes v1
INNER JOIN votes v2 ON (v1.item_id = v2.item_id)
WHERE v1.userID = 'userA'
AND v2.userUD = 'userB'
于 2009-02-04T20:31:41.467 に答える
3

最初に両方のユーザーを知るのではなく、単一のユーザーに対してこれを実行して、最も近いユーザーを見つける場合:

SELECT
     v2.userID,
     COUNT(*) AS matching_items,
     SUM(CASE WHEN v2.direction = v1.direction THEN 1 ELSE 0 END) AS matching_votes
FROM
     Votes v1
INNER JOIN Votes v2 ON
     v2.userID <> v1.userID AND
     v2.itemID = v1.itemID
WHERE
     v1.userID = @userID
GROUP BY
     v2.userID

その後、必要に応じて制限することができます (上位 10 件、上位 20 件、すべてを返すなど)。

これはまだテストしていないので、期待どおりに動作しない場合はお知らせください。

于 2009-02-04T20:48:00.403 に答える
2

これがあなたを近づけるはずの例です:

SELECT COUNT(*)
FROM (
      SELECT u1.userID
      FROM vote u1, vote u2
      WHERE u1.itemID = u2.itemID
      AND u1.userID = user1
      AND u2.userID = user2)
于 2009-02-04T20:35:25.780 に答える
2

userID1がuserID2と比較されていると仮定します

彼らが共通して持っている投票数を見つけるために:

SELECT COUNT(*)
FROM Votes AS v1
INNER JOIN Votes AS v2 ON (v2.userID = 2
                            AND v2.itemID = v1.itemID)
WHERE v1.userID = 1;

彼らも同じ投票をしたときを見つけるために:

SELECT COUNT(*)
FROM Votes AS v1
INNER JOIN Votes AS v2 ON (v2.userID = 2
                            AND v2.itemID = v1.itemID
                            AND v2.direction = v1.direction)
WHERE v1.userID = 1;
于 2009-02-04T20:35:46.637 に答える
2

自己結合が必要です。ここにあなたが尋ねたすべてがあります:

SELECT v1.userID user1, v2.userID user2,
  count(*) n_votes_in_common,
  sum(case when v1.direction = v2.direction then 1 else 0 end) n_votes_same_direction,
  (n_votes_same_direction * 100.0 / n_votes_in_common) crude_similarity_percent 
FROM votes v1
INNER JOIN votes v2
ON v1.item_id = v2.item_id
于 2009-02-04T20:40:19.920 に答える