选择具有几个相同参数的行

时间:2017-05-05 14:23:04

标签: mysql sql django

我有3张牌桌:Student(id, username)Skill(id, value)StudentSkill(id, student_id, skill_id) 在django模特中,他们喜欢这样(简短版):

class Student(models.Model):
    username = models.CharField(max_length = 50, unique = True)

class Skill(models.Model):
    value = models.CharField(max_length = 50, unique = True)

class StudentSkill(models.Model):
    student = models.ForeignKey(Student, on_delete=models.CASCADE)
    skill = models.ForeignKey(Skill, on_delete=models.CASCADE)

我需要编写一个请求,该请求返回具有特定技能的学生的查询集。

例如,我在数据库中有以下数据:

Student
id     | username
------ | ------
1      | user1
2      | user2
3      | user3

Skill
id     | value
------ | ------
1      | s1
2      | s2
3      | s3

StudentSkill
id     | student_id | skill_id
------ | ---------- | --------
1      | 1          | 1
2      | 2          | 1
3      | 2          | 2
4      | 3          | 1
5      | 3          | 2
6      | 3          | 3

user1有1项技能:(s1
user2有两项技能:(s1s2
user3有3项技能:(s1s2s3

如果我需要接听s1s2的学生,我必须user2user3 如果s1 - > user1user2user3
如果s2 - > user2user3
如果s1s3 - > user3

我知道解决这个问题的两种方法,但我认为它们都很糟糕。

第一:

students = Student.objects.raw('''
    SELECT t1.* FROM (
        SELECT student.* FROM student
            INNER JOIN studentskill ON studentskill.student_id = student.user_id
            INNER JOIN skill ON skill.id = studentskill.skill_id
            WHERE skill.id = 1
        ) AS t1
        INNER JOIN studentskill ON studentskill.student_id = t1.user_id
        INNER JOIN skill ON skill.id = studentskill.skill_id
        WHERE skill.id = 2
    ''')  

其次(我没有检查过这段代码,可能有bug):

students = Student.objects.filter(studentskill__skill__id = 1
    ).select_related('studentskill', 'skill'
    ).only('student', 'studentskill', 'skill__id' )
students.filter(studentskill__skill__id = 2)

1 个答案:

答案 0 :(得分:0)

您可以使用分组并具有不同的技能= 2

    select SELECT student.id, student.username
    FROM student
    INNER JOIN studentskill ON studentskill.student_id = student.user_id
    INNER JOIN skill ON skill.id = studentskill.skill_id
    WHERE skill.id in (1,2) 
    group by student.id, student.username
    havinge count(distinct studentskill.skill_id)= 2