0

这是我第一次在这里问

所以基本上我有 3 个表,一个存储客户基本数据,一个存储基于问题的用户属性,另一个存储用户偏好,其中存储了相同属性的多个选项。

让我们说...

表用户:

userid, username, useremail, userphone

表属性:

attributeid,attributeofuser, attributename(number), attribute value(number)

表首选项:

preffid, preffofuser, preffattributename(number), preffattributevalue(number)

属性名和属性值是存储在另一个表中的属性和值的编号。

如果 preffattributevalue 为 0 表示没关系,所以任何属性都可以

所以我需要的是根据他们的属性找到与特定用户的偏好匹配的所有用户,并按百分比进行,所以不仅100%匹配也更少。

我已经完成了看起来非常繁重的查询循环并寻找更好的选择。提前致谢

4

2 回答 2

1

正如 Marty McVry 所说,这是一个有趣的问题。这是我的解决方案。请注意,我冒昧地重命名了您的表格...

架构:

CREATE TABLE user (id int, username varchar(200), info varchar(200));
CREATE TABLE attr (id int, user_id int, a_name varchar(200), a_value varchar(200));
CREATE TABLE pref (id int, user_id int, pa_name varchar(200), pa_value varchar(200));

查询:

SELECT looker.username AS looker_name, 
    CONCAT("likes ",match_candidate.username,"\'s") AS candidate_name, 
    GROUP_CONCAT(" ", CONCAT(attr.a_value," ", attr.a_name)) AS attributes,
    COUNT(attr.a_name) AS match_count
FROM pref 
  INNER JOIN attr ON attr.a_name = pref.pa_name 
  INNER JOIN user AS match_candidate ON match_candidate.id = attr.user_id
  INNER JOIN user AS looker ON looker.id = pref.user_id
WHERE (pref.pa_value IS NULL OR pref.pa_value = attr.a_value) AND
  pref.user_id = 101 AND looker.id <> match_candidate.id
GROUP BY candidate_name
ORDER BY match_count DESC;

解释:

我们获取 pref 表并将其与 attr 表连接以获取匹配的属性名称。attr 表可以与 user 表连接以获取候选人的名称。最后,我们可以连接到“观察者”,即希望他/她的偏好匹配的用户。这是通过与用户表的第二次连接完成的,但这次当然是在 pref.user_id 上。现在我们需要整理出不匹配的属性值。我们通过强制所有结果行具有 NULL 作为首选项属性值或该属性值等于匹配候选者的属性值(属性名称已与连接条件匹配)来做到这一点。要获得特定“查找者”的匹配候选者,我们还必须将其包含在WHERE子句 ( pref.user_id = 101) 中。这里101只是一个用户 ID 的示例。最后,我们必须确保我们不会将观察者与他/她自己匹配(以防自己的偏好与自己的属性匹配)。SELECT字段只是一些玩弄GROUP_CONCAT和来组合我们使用的CONCAT 匹配属性GROUP BY

我做了一个sqlfiddle来玩。所以在我的示例中,我使用字符串作为属性名称和值。pref 值中的 NULL 意味着没有偏好意味着候选者的所有属性值都匹配。

旁注:您可以对 attr 和 pref 使用同一个表,并添加一个定义其类型的字段。

更新旁注:我现在更新了这个答案。如果您检查了早期版本的小提琴,请再次点击链接,因为它可能已经改变。

于 2013-04-28T09:53:39.413 回答
0

有趣的问题...

下面的查询未经测试,所以不确定它是否会工作。

    SELECT u.*,
           sub.num_match
      FROM users AS u
INNER JOIN (   SELECT a.attributeofuser AS uid,
                      COUNT(a.attributeid) AS num_match
                 FROM preferences AS p
            LEFT JOIN attributes AS a
                   ON p.preffattributename = a.attributename
                WHERE p.prefofuser = $user_id
                  AND p.prefofuser <> a.attributeofuser
             GROUP BY a.attributeofuser                      ) sub
        ON u.userid = sub.uid
  ORDER BY sub.num_match DESC;

首先,子查询获取所有用户的用户 ID,这些用户至少有 1 个属性与请求用户的偏好相同。它还将返回它们共有的属性数量,因此您可以稍后计算匹配百分比。

使用来自子查询的数据,您可以从您的users-table 中获取用户数据。

使用另一个查询来获取请求用户输入的偏好数量,您可以计算匹配百分比!

于 2013-04-28T09:15:59.083 回答