我有两张桌子。我希望得到类似的百分比记录。
请查看我的代码:
用户
+----+------------+----------+
| id | fname | lname |
+----+------------+----------+
| 1 | sanjib | pradhan |
| 2 | aruna | avipsa |
| 3 | chinu | sahu |
| 4 | sradha | behera |
| 5 | debasish | dash |
| 6 | pikun | behera |
| 7 | pradep | hardy |
+----+------------+----------+
user_tags
+-----+---------+------------+
| id | user_id | tag |
+-----+---------+------------+
| 1 | 1 | php |
| 2 | 1 | java |
| 3 | 2 | java |
| 4 | 1 | dotnet |
| 5 | 2 | oracle |
| 6 | 3 | oracle |
| 7 | 3 | python |
| 8 | 4 | sql |
| 9 | 3 | java |
+-----+---------+------------+
有两个表users
和user_tags
我需要3个记录百分比。 user_id 1有3个标签php, java, dotnet
user_id 2有2个标签,user_id 3有3个标签,4有1个标签。
假设我的查询基于users表中的id = 2。标签表上有2个标签。我需要这两个标签与其他用户标签类似。
USER_ID = 2
标记= java中,预言
USER_ID = 1
tags = php,java,dotnet(匹配标记java存在 - 百分比应该是匹配标记数/总标记数)表示1/3
USER_ID = 3
tags = oracle,python,java
2 tags matches(java and oracle)
%应为2/3
user_id = 4,tag = sql(没有匹配标记,因此百分比为0%)
如何使用MySQL和php代码管理它?
答案 0 :(得分:3)
我们可以通过将带有标签的所有用户加入到用户2及其标签中来获得您想要的答案。然后我们只计算适当的值来得到你的百分比。
select u1.id,
count(ut2.tag) matches,
count(ut1.tag) total,
count(ut2.tag) / count(ut1.tag) pct
from users u1
inner join user_tags ut1
on u1.id = ut1.user_id
left join
users u2
inner join user_tags ut2
on u2.id = ut2.user_id
on ut2.tag = ut1.tag
and u2.id = 2
where u1.id <> 2
group by u1.id
这是如何工作的?在group by和aggregate函数之前,返回的行如下所示:
id fname lname id user_id tag id fname lname id user_id tag
1 sanjib pradhan 2 1 java 2 aruna avipsa 3 2 java
3 chinu sahu 9 3 java 2 aruna avipsa 3 2 java
3 chinu sahu 6 3 oracle 2 aruna avipsa 5 2 oracle
1 sanjib pradhan 1 1 php (null) (null) (null) (null) (null) (null)
1 sanjib pradhan 4 1 dotnet (null) (null) (null) (null) (null) (null)
3 chinu sahu 7 3 python (null) (null) (null) (null) (null) (null)
4 sradha behera 8 4 sql (null) (null) (null) (null) (null) (null)
如您所见 - 左侧用户的标记与右侧用户的标记不匹配,输入空值。 mysql中的count
函数忽略空值,不计算它们。因此,当我们按u1.id分组(最左边的id值)并计算他们拥有的标签数量(ut1.tag
)时,我们得到所有标签的总和。但是,当我们计算ut2.tag
的值时,我们只得到不是null
的总数,即只有匹配的总数。这可以让我们获得你的百分比。
编辑评论
您在评论中添加了要求,可以同时与多个用户进行比较,因为这意味着它可能会多次匹配同一个标记,我们只需计算不同的元素。
select u1.id,
count(distinct ut2.tag) matches,
count(ut1.tag) total,
count(distinct ut2.tag) / count(ut1.tag) pct
from users u1
inner join user_tags ut1
on u1.id = ut1.user_id
left join
users u2
inner join user_tags ut2
on u2.id = ut2.user_id
on ut2.tag = ut1.tag
and u2.id IN (2,3)
where u1.id NOT IN (2,3)
group by u1.id
having count(ut2.tag) > 0;
使用您更新的小提琴here