2013-04-05 46 views
1

我有一個模型USERPROFILE的是,與所謂的技巧 另一個表的多對多關係,我也有一個模型組與所謂的技巧多對多的Django的sql

另一個表的多對多的關係,我想作這個查詢會計算出用戶配置文件與每個組共有的技能數量。

我也希望進行查詢,將算我的一個特定的用戶配置文件已經在與他人的用戶配置文件cummon技能數量

有人能幫助我做到這一點。 謝謝

型號:

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) 

於是我找到了一種方法來做到這一點團體

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') 

但我不知道如何將用戶之間做

+1

請分享模式。 – karthikr 2013-04-05 19:49:34

+0

分享謝謝 – 2013-04-05 20:04:59

回答

1

您的第一個查詢是計算特定用戶配置文件中用戶與每個組共享的技能數量。在你的文章中,你將展示一種使用子查詢的方法。然而,在某些數據庫子查詢有更差的性能比加入,所以你可能會有興趣看怎麼辦使用相同的結果聯接,而不是子查詢得到:

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 

在Django中,你可以運行使用raw SQL queryGroup型號:

Group.objects.raw(''' ... SQL as above ... ''', [profile.id]) 

現在應該很容易看到如何執行你的第二個查詢。也就是說,來算,爲特定用戶配置文件中,與對方用戶的用戶共享的技能數量:

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 

同樣,在Django可以運行使用原始的SQL查詢,這個時候就UserProfile型號:

UserProfile.objects.raw(''' ... SQL as above ... ''', [profile.id]) 
+0

嗨Gareth謝謝,但事情是,skills_count不是唯一的子查詢我有大量的子查詢來獲得其他計數,所以通過一個原始的做可能會更快,但要寫一些SQL INNER JOIN ...我不知道我是否可以這樣做,這將是一場噩夢......但你說得對,如果子查詢花費太多時間,我可能會這樣做。現在我在網站上沒有那麼多東西,但是將來我會這樣做,所以我可能需要重新考慮並使用原始數據。 – 2013-04-06 18:34:14

0
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')