2016-06-06 3 views
1

Je n'ai pas beaucoup de connaissance de mysql. Mon modèle django est comme suit:Requête Mysql en vue django

class Exercise_state(models.Model): 
    exercise = models.ForeignKey(Exercise, blank=True, null=True) 
    user = models.ForeignKey(User, blank=True, null=True) 
    intensity_level = models.IntegerField(default='1') 
    progress = models.IntegerField(default='0') 
    current_date = models.DateField(auto_now=True) 
    user_rating = models.IntegerField(default='0') 

Je veux récupérer le nombre de user_id de qui SATISFAIRE exercise_id = 1 correspondant intensity_level = 7 et ainsi de suite pour tous les années exercise_id jusqu'à 7. En bref, les utilisateurs qui ont atteint intensity_level = 7 tous les exercices.

J'ai écrit une requête qui est la suivante:

select count(user_id) from demo_exercise_state where 
exercise_id=1 and intensity_level=7 and 
exercise_id=2 and intensity_level=7 and 
exercise_id=3 and intensity_level=7 and 
exercise_id=4 and intensity_level=7 and 
exercise_id=5 and intensity_level=7 and 
exercise_id=6 and intensity_level=7 and 
exercise_id=7 and intensity_level=7; 

Pour autant que je peux recouper les résultats de ma base de données directement Aucun utilisateur n'a encore complété sa formation (c.-à-qui a atteint intensity_level = 7 dans tous les types d'exercice), donc il renvoie le compte comme «0».

Je suis sûr que cette requête peut être optimisée car il y a beaucoup de répétition, mais je ne sais pas comment.

Je veux également exécuter la même chose (c'est-à-dire obtenir le même résultat) dans ma vue django. Là j'ai quelque chose comme

all_exercise_finish_count = Exercise_state.objects.filter(exercise_id=1, intensity_level=7).count() 

Comment est-ce que je peux refléter la même chose dans cette vue de django?

+0

Un utilisateur peut faire un exercice avec 'intensity_level = 7' plus d'une fois? – AKS

+0

Oui mais ce n'est pas grave car sa progression n'est pas enregistrée après intensité_level = 7 – Nitish

Répondre

1

Mise à jour changer complètement ma réponse parce que la discussion qui a suivi dans le commentaire a clairement indiqué que les intentions étaient tout à fait OPs différent de ce qu'il est apparu être.

Vous pouvez trouver les utilisateurs qui ont terminé tous les 7 exercices à intensité 7 de la manière suivante

from django.db.models.import Count 

Exercise_state.objects.annotate(
    c = Count('exercise').filter(c=7, exercise_id= 7) 

Première forme de la réponse est ci-dessous:

La requête brute d'origine peut être grandement simplifiée avec between

expr entre min et max

I f expr est supérieur ou égal à min et expr est inférieur ou égal à à max, BETWEEN renvoie 1, sinon il renvoie 0. Ceci est équivalent à l'expression (min < = expr ET expr < = max) si tous les les arguments sont du même type. Dans le cas contraire, la conversion de type s'effectue conformément aux règles décrites à la Section 13.2, «Conversion de type dans l'expression Évaluation», mais s'applique à tous les trois arguments.

select count(user_id) from demo_exercise_state where 
exercise_id BETWEEN 1 and 7 AND intensity_level=7 

Et la requête django peut être simplement

all_exercise_finish_count = Exercise_state.objects.filter(exercise_id__gte=1, intensity_level=7, excercise_id__lte=7).count() 
+1

Encore plus simple avec ['range'] (https://docs.djangoproject.com/fr/1.9/ref/models/querysets/#range) : 'exercise_id__range = (1, 7)'. –

+0

Malheureusement, la requête initiale et la requête en réponse me donnent des résultats différents. Ma requête initiale me donne '0' alors que votre requête m'a donné '1'!Je pense qu'il a considéré tout exercice_id entre 1 et 7 avec intensité_level 7 et pas tous exercice_id de 1 à 7 avec intensité_level '7' – Nitish

+0

hein no. Ma requête SQL brute est l'équivalent exact de votre requête SQL brute. tous ces ANDs supplémentaires sont redundants – e4c5