在我的网站上,我允许用户选择他们喜欢或感兴趣的内容。这是使用预定义的下拉菜单完成的,因此每次用户登录网站时,他们都会获得拥有和他们一样兴趣。
这是通过使用MySQL WHERE子句获取登录用户的兴趣(存储在db中)并与站点上的其他用户匹配来完成的。但我遇到的问题是如何显示每个用户旁边的百分比或分数,以显示他们与登录用户兴趣的匹配程度。
例如:
如果所有用户都匹配,则每个用户都有5种不同的兴趣。
表结构示例:
CREATE TABLE IF NOT EXISTS `helloworld` (
`id` int(9) NOT NULL AUTO_INCREMENT,
`like1` varchar(300) NOT NULL,
`like2` varchar(300) NOT NULL,
`like3` varchar(300) NOT NULL,
`name` varchar(300) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;
示例查询:
SELECT * FROM helloworld WHERE like1='football' AND like2='art'
我在考虑使用COUNT
功能,但我不确定?或者我应该使用子查询?
编辑:我使用PHP作为服务器端语言。用户不能键入自己的喜欢,必须使用预定义的列表。
答案 0 :(得分:0)
你和用户之间有很多关系。您的表违反了1NF - 您有like
列的“重复组”。相反,有一个单独的关联表来处理这个:
create table user_likes (
user_id int(9) NOT NULL,
like_name varchar(300) NOT NULL
);
现在你可以使用更简单的查询来获得匹配的数量 - 我会留给你研究:)
提示:您可以使用位掩码来帮助确定匹配,为每个不同的like_name分配预定义的2位数幂(help是一个like_names表)。
答案 1 :(得分:0)
首先,我认为你需要一个不同的架构。你拥有的那个将使你的任务非常困难,因为它不够灵活。我推荐这样的东西:
CREATE TABLE `users` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(300) NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `likes` (
`user` INT NOT NULL,
`interest` VARCHAR NOT NULL,
PRIMARY KEY (`user`,`interest`)
);
(对不起,我不记得如何在MySQL中设置FK关系,但我相信你可以很容易地解决这个问题。)
然后,确定每个用户的“喜欢”数量:
SELECT COUNT(*)
FROM users
JOIN likes ON likes.user=users.id
WHERE users.name = 'bob';
然后确定两个用户有多少共同点:
SELECT COUNT(*)
FROM users AS u1
JOIN likes AS l1 ON (l1.user = u1.id)
JOIN likes AS l2 ON (l1.interest = l2.interest)
JOIN users AS u2 ON (l2.user = u2.id)
WHERE u1.name = 'bob'
AND u2.name = 'alice';
然后根据这三个数字,您可以根据需要计算百分比 - 可能在您的客户端代码中,但如果需要,您可以使用子选择在所有SQL端执行。
示例:
USERS:
id | name
----+-------
1 | bob
2 | alice
LIKES:
user | interest
------+----------
1 | fish
1 | baseball
2 | fish
2 | cooking
2 | baseball
运行bob
和alice
的第一个查询将显示bob具有 2 兴趣,并且Alice具有 3 兴趣。然后运行第二个查询将显示他们的bob和alice一起拥有 2 共享兴趣。
然后你可以向鲍勃展示爱丽丝分享他100%的兴趣(2/2 = 100%),你可以向爱丽丝展示鲍勃共享66%(2/3 = 66%)的兴趣。
答案 2 :(得分:0)
你最好在PHP级别检查一下。考虑到每个用户的兴趣,您可以使用count()对array_intersect()的结果进行评分,以比较访问者和其他用户的兴趣(http://www.php.net/manual/en/function.array-intersect。 PHP)。如果你允许5个兴趣,那就是(5 * count(array_intersect({params})))%。不匹配,0%,4场比赛,80%。
答案 3 :(得分:0)
我是这样做的。假设$ like1,$ like2和$ like3是当前用户的值:
SELECT (IF(like1='$like1',1,0) + IF(like2='$like2',1,0) + IF(like3='$like3',1,0))/3*100 match_percent,
COUNT(id)
FROM helloworld
GROUP BY match_percent;
答案 4 :(得分:0)
这将使用您当前的架构:
select
t2.id,
t2.name
sum(
t1.like1 in (t2.like1, t2.like2, t2.like3, t2.like4, t2.like5) +
t1.like2 in (t2.like1, t2.like2, t2.like3, t2.like4, t2.like5) +
t1.like3 in (t2.like1, t2.like2, t2.like3, t2.like4, t2.like5) +
t1.like4 in (t2.like1, t2.like2, t2.like3, t2.like4, t2.like5) +
t1.like5 in (t2.like1, t2.like2, t2.like3, t2.like4, t2.like5)
) * 20 as percent_match
from helloworld t1
left join helloworld t2 on t1.id != t2.id
group by 1, 2
order by 3 desc;
这是有效的,因为mysql中的true
是1
- 总结真相将总计匹配数。