2017-05-05 4 views
1

Ich habe 3 Tabellen: Student(id, username), Skill(id, value) und StudentSkill(id, student_id, skill_id).
In django Modelle loook sie wie die (kurze Version):Wählen Sie Zeilen mit ein paar gleichen Parametern

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) 

Ich brauche eine Anfrage zu schreiben, die eine queryset von Schülern mit spezifischen Fähigkeiten zurückgibt.

Zum Beispiel habe ich die folgenden Daten in der Datenbank:

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 hat 1 Geschicklichkeit: (s1)
user2 hat 2 Fähigkeiten: (s1 und s2)
user3 hat 3 Fähigkeiten: (s1, s2 und s3)

Wenn ich Student nehmen muss ts die s1 und s2 haben, muss ich user2 und user3
nehmen Wenn s1 ->user1, user2 und user3
Wenn s2 ->user2 und user3
Wenn s1 und s3 ->user3

I kenne 2 Möglichkeiten, um dieses Problem zu lösen, aber ich denke, sie sind beide schlecht.

Erstens:

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

Sekunde (Ich habe diesen Code nicht überprüft, kann es Fehler haben):

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

Antwort

0

Sie eine Gruppe von und mit einzelnen Fähigkeiten = 2

verwenden könnte
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 
+0

Es funktioniert. Eine Frage: – Sskeptix

+0

OK .. dann .. fragen .. – scaisEdge

+0

oder wenn meine Antwort richtig ist, bitte markieren Sie es als akzeptiert ... siehe hier http://meta.stackexchange.com/questions/5234/how-does- Annahme-eine-Antwort-Arbeit – scaisEdge

Verwandte Themen