數據庫如何高級快速的查詢是必須掌握的技能之一,除去通常的增刪改掌握高級語法可讓你更加快速有效的獲取你想要的數據python
from django.db import models
class Publisher(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
addr = models.CharField(max_length=32)
phone = models.IntegerField
def __str__(self):
return self.name
# 做者查書,設計到做者裏面
class Author(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=16)
author_detail = models.OneToOneField("AuthorDetail")
# 多對多
books = models.ManyToManyField(to="Book")
def __str__(self):
return self.name
class Book(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=6)
price = models.DecimalField(max_digits=5, decimal_places=2)
publish_day = models.DateField(auto_now_add=True)
# 書-出版社 多對一關聯
publisher = models.ForeignKey(to="Publisher", to_field="id")
def __str__(self):
return self.title
class AuthorDetail(models.Model):
id = models.AutoField(primary_key=True)
city = models.CharField(max_length=32)
email = models.EmailField()
def __str__(self):
return self.city
複製代碼
例如:git
queryset = Book.objects.all().aggreate(Avg("price"))
{'price__avg': 192.593333} # 查詢結果(未指定鍵名)
models.Book.objects.all().aggregate(avg_price=Avg("price"))
{'avg_price': 192.593333} # 查詢結果(指定鍵名)
# 若是要指定多個鍵值對能夠增長參數
models.Book.objects.all().aggregate(Avg('price'), Min('price'), Sum('price'))
{'price__avg': 192.593333, 'price__max': Decimal('233.33'), 'price__min': Decimal('111.12'), 'price__sum': Decimal('577.78')}
複製代碼
models.Book.objects.all().annotate(authorNum=Count("author"))
Output: <QuerySet [<Book: 書一>, <Book: 書二>, <Book: 書三>]>
book_list = models.Book.objects.all().annotate(authorNum=Count("author"))
for i in book_list:
print(i.authorNum)
OutPut:
2
2
1
複製代碼
# 注意在反向查詢字段須要雙下劃線
models.Publisher.all().annotate(min_price=Min("book__price"))
for i in queryset:
print(i.min_price)
Output:
111.12
12.00
456.00
785.00
# 當須要篩選其餘的字段或者須要返回特定的字段值
models.Publisher.filter(name='zhan').values('phone','book__author').annotate(min_price=Min("book__price"))
for i in queryset:
print(i)
Output:
{'phone': 18895309883, 'book__author': 'zhan', 'book__price': 111.11 }
複製代碼
# ps:gt在數據庫篩選表示大於等於,lt小於等於
models.objects.all().annotate(au=Count("author")).filter(au__gt=1)
Output:
[queryset <book1> <book2>] # 本身看的懂就行
# 能夠對上面的查詢語句進行oder_by下
models.objects.all().annotate(au=Count("author")).filter(au_gt=1).oder_by(au)
複製代碼
# 查詢語句中name是指做者的名字,結果仍是會以鍵值對展現
models.Author.objects.all().annotate(total=Sum("book_price")).values("name",
"total")
複製代碼
# 查詢結果爲querysetfile:/Users/zhanlingjie/Documents/mypython/SZKJ/eyaos_vm/server/organization/urls.py
models.Book.objects.filter(id__gt= F('price')/2)
複製代碼
models.Author.objects.filter(Q(name="小一") | Q(name="小三"))
<QuerySet [<Author: 小一>, <Author: 小三>]>
Output:
1
2
3
複製代碼
ORM 跨表查詢
class Book(models.Model):
title = models.CharField( max_length=32)
publish=models.ForeignKey(to="Publish",to_field="id")
authors=models.ManyToManyField(to='Author',related_name='bookList') 
class Publish(models.Model):
name=models.CharField( max_length=32)
class Author(models.Model):
name=models.CharField( max_length=32)
ad=models.OneToOneField("AuthorDetail")
class AuthorDetail(models.Model):
telephone=models.BigIntegerField()
基於對象查詢(sql:子查詢)
一對多的關係 (Publish--Book)
正向查詢,按字段:
查詢python這本書的出版社所在的名稱
book_obj=Book.objects.filter(title="python").first()
#print(book_obj.publish.name)
反向查詢,按表名小寫_set:
人民出版社出版過的全部書籍名稱
publish_obj=Publish.objects.filter(name="人民出版社出版").first()
print(publish_obj.book_set.all())
for obj in publish_obj.book_set.all():
print(obj.title)
多對多的關係
正向查詢,按字段:
python這本書全部做者的名字
book_obj=Book.objects.filter(title="python").first()
book_obj.authors.all()
反向查詢,按表名小寫_set:
alex出版過的全部書籍名稱
alex=Author.objects.filter(name="alex").first()
alex.bookList.all()
一對一的關係
正向查詢,按字段:
查詢alex的手機號
alex=Author.objects.filter(name="alex").first()
alex.ad.telephone
反向查詢:按表名小寫
以151開頭的手機號的做者的名字
ad=AuthorDetail.objects.get(telephone__startswith="151")
ad.author.name
基於Queryset和 __(sql:join語句):
正向查詢,按字段
反向查詢,按表名小寫
一對多的關係 (Publish--Book)
查詢python這本書的所在出版社的名稱
Book.objects.filter(title="python").values("publish__name")
for obj in Book.objects.filter(title="python"):
temp={}
temp["publish__name"]=obj.publish.name
人民出版社出版過的全部書籍名稱
Publish.objects.filter(name="人民出版社出版").values("book__title")
多對多的關係
python這本書全部做者的名字
Book.objects.filter(title="python").values("authors__name")
alex出版過的全部書籍名稱
Author.objects.filter(name="alex").values("book__title")
一對一的關係
查詢alex的手機號
Author.objects.filter(name="alex").values("ad__telephone")
以151開頭的手機號的做者的名字
AuthorDetail.objects.filter(telephone__startswith="151").values("author__name")
擴展:
練習1:
查詢python這本書的所在出版社的名稱
Book.objects.filter(title="python").values("publish__name")
Publish.objects.filter(book__title="python").values("name")
練習2:
手機號以151開頭的做者出版過的全部書籍名稱以及出版社名稱
Book.objects.filter(authors__ad__telephone__startswith="151").values("title","publish__name")
分組查詢:
查詢每個出版社出版過的書籍個數
Publish.objects.annotate(Count("book__id"))
select count(*) from publish group by id
複製代碼