4

我进行了一些搜索,但没有找到与我想要实现的目标完全一样的东西。

基本上,我试图找到两个用户投票习惯之间的相似之处。

我有一个表格存储每个单独的投票,其中存储:

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 之间的相似度:

  1. 他们共有的票数。也就是说,他们都在同一个帖子上投票的次数(此时方向无关紧要)。
  2. 他们在共同投票中朝同一个方向投票的次数

(然后简单地将#2 计算为#1 的百分比,以获得粗略的相似性评级)。

我的问题是,我如何找到两个用户的投票集之间的交集?(即我如何充分计算第 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

假设将 userID 1 与 userID 2 进行比较

为了找出他们有多少共同的选票:

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 回答
1

您当然可以将表连接到自身。事实上,这就是你必须要做的。将表连接到自身时必须使用别名。如果您的表没有 PK 或 FK,则必须改用 Union。Union 将删除重复项,Union All 不会。

于 2009-02-04T20:27:54.577 回答