I have a model userprofile that as a manytomany relationship with another table called skill I also have a model group that as a manytomany relationship with another table called skill
I would like to make a query that will count me the number of skills that the userprofile have in common with each group.
I also would like the make a query that will count me the numbers of skills that a specific userprofile has in cummon with others user profile
Could someone help me to do this. Thank you
the models :
class UserProfile(models.Model):
slug = models.SlugField(max_length=200)
user = models.ForeignKey(User, unique =True)
skills = models.ManyToManyField(Skills,null=True, blank=True)
courses = models.ManyToManyField(Course,null=True, blank=True)
class Group(models.Model):
slug = models.SlugField(max_length=200)
name = models.CharField(max_length=200)
skills = models.ManyToManyField(Skills,null=True, blank=True)
class Skills(models.Model):
slug = models.SlugField(max_length=200)
name = models.CharField(max_length=200)
So I found a way to do it for groups
groupRecommendation = Group.objects.extra(
select={
'skills_count': """
SELECT COUNT(*) FROM axiom_alto_userprofile_skills
JOIN axiom_alto_group_skills on axiom_alto_userprofile_skills.skills_id = axiom_alto_group_skills.skills_id
WHERE axiom_alto_group_skills.group_id= axiom_alto_group.id AND axiom_alto_userprofile_skills.userprofile_id = %d """ % profile.id,
},
).order_by('-skills_count')
But I don't know how to do it between users
Your first query is to count, for a specific user profile, the number of skills that user shares with each group. In your post, you show a way to do it using a subquery. However, in some databases subqueries have much poorer performance than joins, so you might be interested to see how to do get the same results using a join instead of the subquery:
SELECT G.id, G.slug, G.name, COUNT(GS.id) AS skills_count
FROM axiom_alto_group G
INNER JOIN axiom_alto_userprofile_skills US
ON US.userprofile_id = %s
LEFT OUTER JOIN axiom_alto_group_skills GS
ON GS.group_id = G.id AND US.skills_id = GS.skills_id
GROUP BY G.id, G.slug, G.name
ORDER BY skills_count DESC
In Django you can run that using a raw SQL query on the Group
model:
Group.objects.raw(''' ... SQL as above ... ''', [profile.id])
It should now be easy to see how to perform your second query. That is, to count, for a specific user profile, the number of skills that user shares with each other user:
SELECT U.id, U.slug, U.user, COUNT(US2.id) AS skills_count
FROM axiom_alto_userprofile U
INNER JOIN axiom_alto_userprofile_skills US1
ON US1.userprofile_id = %s
LEFT OUTER JOIN axiom_alto_userprofile_skills US2
ON US2.userprofile_id = U.id AND US2.skills_id = US1.id
GROUP BY U.id, U.slug, U.user
ORDER BY skills_count DESC
Again, in Django you can run that using a raw SQL query, this time on the UserProfile
model:
UserProfile.objects.raw(''' ... SQL as above ... ''', [profile.id])
groupRecommendation = Group.objects.extra(
select={
'skills_count': """
SELECT COUNT(*) FROM axiom_alto_userprofile_skills
JOIN axiom_alto_group_skills on axiom_alto_userprofile_skills.skills_id = axiom_alto_group_skills.skills_id
WHERE axiom_alto_group_skills.group_id= axiom_alto_group.id AND axiom_alto_userprofile_skills.userprofile_id = %d """ % profile.id,
},
).order_by('-skills_count')
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.