Django的orm練習---多表查詢

Django的orm練習---多表查詢

 表關係以下html

表結構 : django

複製代碼
from django.db import models

# Create your models here.


# 多對多----->>>老師和班級
# 一對多----->>>學生和班級  : 一個班級能夠有多個學生----學生設置主鍵
#               老師和課程  : 一個老師能夠教多門課程----課程設置主鍵
#
# 一對一---->>>>班級和年級 : 一個班級對應一個年級
#
# 成績表----學生 : 一對多.  一個學生多個成績 /
# 成績表----課程 : 一對多

# 學生
class Student(models.Model):
    sid=models.AutoField(primary_key=True)
    sname=models.CharField(max_length=32)
    gender=models.CharField(max_length=32)
    class_id=models.ForeignKey(to="Class",on_delete=models.CASCADE)

# 班級
class Class(models.Model):
    cid=models.AutoField(primary_key=True)
    caption=models.CharField(max_length=32)
    grade=models.ForeignKey(to="Class_grade",on_delete=models.CASCADE)
    teachers=models.ManyToManyField(to="Teacher")

# 年級
class Class_grade(models.Model):
    gid=models.AutoField(primary_key=True)
    gname=models.CharField(max_length=32)

# 課程
class Course(models.Model):
    cid=models.AutoField(primary_key=True)
    cname=models.CharField(max_length=32)
    teacher=models.ForeignKey(to="Teacher",on_delete=models.CASCADE)

# 老師
class Teacher(models.Model):
    tid=models.AutoField(primary_key=True)
    tname=models.CharField(max_length=32)


#成績
class Score(models.Model):
    sid=models.AutoField(primary_key=True)
    student=models.ForeignKey(to="Student",on_delete=models.CASCADE)
    course=models.ForeignKey(to="Course",on_delete=models.CASCADE)
    score=models.IntegerField()
複製代碼

 

習題 : app

複製代碼
# 一、自行建立測試數據;
# 二、查詢學生總人數;
# 三、查詢「生物」課程和「物理」課程成績都及格的學生id和姓名;
# 四、查詢每一個年級的班級數,取出班級數最多的前三個年級;
# 五、查詢平均成績最高的學生的id和姓名以及平均成績;
# 六、查詢每一個年級的學生人數;
# 七、查詢每位學生的學號,姓名, 平均成績;
# 八、查詢學生編號爲「2」的學生的姓名、該學生成績最高的課程名及分數;
# 九、查詢姓「李」的老師的個數和所帶班級數;
# 十、查詢班級數小於5的年級id和年級名;
# 十一、查詢教過課程超過2門的老師的id和姓名;
# 十二、查詢學過編號「1」課程和編號「2」課程的同窗的學號、姓名;
# 1三、查詢所帶班級數最多的老師id和姓名;
# 1四、查詢有課程成績小於60分的同窗的學號、姓名;
# 1五、查詢男生、女生的人數,按倒序排列;
# 1六、 查詢各個課程及相應的選修人數;
# 1七、 查詢同時選修了物理課和生物課的學生id和姓名;
# 1八、 檢索「3」課程分數小於60,按分數降序排列的同窗學號;
# 1九、 查詢每門課程的平均成績,結果按平均成績升序排列,平均成績相同時,按課程號降序排列;
# 20、 查詢各科成績最高和最低的分:以以下形式顯示:課程ID,最高分,最低分;
複製代碼

 

答案 : post

複製代碼
from django.shortcuts import render,HttpResponse,redirect

from app01.models import Class,Course,Teacher,Student,Score,Class_grade

from django.db.models import F, Q

from django.db.models import Avg,Max,Sum,Min,Count

# Create your views here.

# values.annotate() : 按字段分組
# annotate() : 按id,name...分組,屬於一列是一組

def query(request):

    # 2 . 查詢學生總人數
    ret=Student.objects.count()
    print("------>",ret)   # {'c': 3}

    # 3 . 查詢「生物」課程和「物理」課程成績都及格的學生id和姓名;
    ret = Student.objects.filter(score__course__cid=3,score__score__gt=59).filter(score__course__cid=1,score__score__gt=59).values("sname", "sid")
    print("----------------", ret)

    # 先去篩選選課在生物和物理之間的,而且建立大於60的學生id,在分組查看選課數,而後篩選選課數等於2的
   ret=Score.objects.filter(course__cname__in=["生物","物理"],score__gt=60).values("student__tid").annotate(c=Count("course")).filter(c=2)


    # 4.查詢每一個年級的班級數,取出班級數最多的前三個年級;
    ret=Score.objects.values("student").annotate(avg_score=Avg("score")).order_by("-avg_score").values("student__sname","student__pk","avg_score")[0]
    print(ret)

    ret=Class.objects.values("grade__gname").annotate(c=Count("caption")).order_by("-c")[:3]
    print("------>",ret)

    # 5.查詢平均成績最高的學生的id和姓名以及平均成績;
    ret=Grade.objects.annotate(c=Count("klass__student__pk")).values("gname","c")
    print(ret)

    ret=Student.objects.values("sid","sname").annotate(scoreAvg = Avg("score__score")).order_by("-scoreAvg")[:1]
    print("------>", ret)

    # 6.查詢每一個年級的學生人數;
    ret=Student.objects.values("sid","sname").annotate(avg_score=Avg("score__score"))
    print(ret)

    ret=Student.objects.annotate(avg_score=Avg("score__score")).values("sid","sname","avg_score")

    ret=Class.objects.values("grade__gname").annotate(c=Count("student"))
    print("-------->",ret)

    # 7 . 查詢每位學生的學號,姓名,平均成績;
    ret=Student.objects.values("sid","sname").annotate(scoreAvg=Avg("score__score"))
    print("-------->", ret)

    ret=Score.objects.filter(student__pk=2).order_by("-score").values("student__sname","course__cname","score")[0]
    print(ret)

    # 八、查詢學生編號爲「2」的學生的姓名、該學生成績最高的課程名及分數;
    ret=Student.objects.filter(sid="2").annotate(scoreMax=Max("score__score")).order_by('-scoreMax')[0:1].values("sname","score__course__cname","scoreMax")
    ret2=Student.objects.filter(sid="2").values("score__course").order_by("-score__score").values("sname","score__course__cname","score__score")[:1]
    print("-------->", ret)
    print("-------->", ret2)

    # 九、查詢每個姓「李」的老師所帶班級數;;
    ret=Teacher.objects.filter(tname__istartswith="李").annotate(c=Count("classes")).values("tname","c")
    print(ret)


     # 10 . 查詢班級數小於5的年級id和年級名;
    ret=Class_grade.objects.annotate(c=Count("class")).filter(c__lt=2).values("gid","gname")
    print("--------", ret)

    ret=Grade.objects.annotate(c=Count("klass")).filter(c__lt=5).values("pk","gname")


    # 11 . 查詢教過課程超過2門的老師的id和姓名;
    ret=Teacher.objects.annotate(c=Count("course")).filter(c__gt=2).values_list("tid","tname")
    print("--------", ret)


    # 12 . 查詢學過編號「1」課程和編號「2」課程的同窗的學號、姓名;      ????????
    ret=Student.objects.filter(score__course__cid=1).filter(score__course__cid=2).values("sid","sname")
    print("-------",ret)


    # 13 . 查詢所帶班級數最多的老師id和姓名;
    ret=Teacher.objects.annotate(c=Count("class__cid")).order_by("-c").values("tid","tname","c")[0]
    print(">>>>>>>>>>",ret)


    # 14 . 查詢有課程成績小於60分的同窗的學號、姓名;
    ret=Student.objects.filter(score__score__lt=60).values("sid","sname","score__sid").distinct()     #去重
    print("-------",ret)

    ret=Score.objects.filter(score__lt=60).values("student__sname","student__pk").distinct()
    print(ret)


    # 15 . 查詢男生、女生的人數,按倒序排列;
    ret=Student.objects.values("gender").annotate(c=Count("gender")).order_by("-c")
    print("-------",ret)

    # 16 . 查詢各個課程及相應的選修人數;
    ret=Course.objects.annotate(c=Count("score__student")).values("cname","c")
    print("-------", ret)
    ret=Score.objects.values("course").annotate(c=Count(1)).values("course__cname","c")
    print(ret)

    # 17 . 查詢同時選修了物理課和生物課的學生id和姓名;
    ret=Student.objects.filter(score__course__cname="物理").filter(score__course__cname="生物").values("sid","sname")
    print("------->",ret)


    # 18 . 檢索「3」課程分數小於60,按分數降序排列的同窗學號;
    ret=Student.objects.filter(Q(score__course__cid=3),Q(score__score__lt=60)).order_by("-score__score").values("sid")   
    ret=Score.objects.filter(course__cid=3).filter(score__lt=60).order_by("-score").values("student__sid")
    print("------->", ret)

    ret=Score.objects.filter(course_id=3,score__lt=60).order_by("-score").values("student_id")


    # 19 . 查詢每門課程的平均成績,結果按平均成績升序排列,平均成績相同時,按課程號降序排列;
    ret=Score.objects.values("course_id").annotate(scoreAvg=Avg("score")).order_by("scoreAvg","-course_id")     #能夠不用跨表  course_id
    print("------->", ret)


    # 20 . 查詢各科成績最高和最低的分:以以下形式顯示:課程ID,最高分,最低分;
    ret=Score.objects.values("course__cid").annotate(scoreMax=Max("score"),scoreMin=Min("score"))
    print(">>>>>>>>>>>",ret)
   ret=Course.objects.annotate(max_score=Max("score__score"),min_score=Min("score__score")).values("pk","max_score","min_score")



    return HttpResponse("ok")
複製代碼
相關文章
相關標籤/搜索