聚合查询
一 分組查詢概念
Book: id name price publish_date publish
1. 聚合函數可以單獨使用: 將整張表作為一個大的分組,查詢字段只能是聚合結果
select max(price), group_concat(name) from book where id < 10;
2. 聚合函數在分組下使用
select publish_id, max(price) as high_price from book group_by publish_id having max(price) > 50
二 聚合查詢
# 聚合函數使用場景
單獨使用: 不分組,只查聚合結果
分組使用: 按字段分組,可查分組字段和聚合結果
# 導入聚合函數
from django.db.models import Avg, Max, Min, Count, Sum
三 單獨聚合查詢: aggregate
# 語法: aggregate(別名=聚合函數('字段'))
# 規則:
1. 可以同時對多個字段進行聚合處理: aggregate(別名1=聚合函數1('字段1'), ..., 別名n=聚合函數n('字段n'))
2. 方法返回值為dict類型
3. 是QuerySet對象方法
# eg:
Book.objects.all().aggregate(high_price=Max('price'))
四 組聚合查詢 annotate
# 語法:
values('分組字段').annotate(別名=聚合函數('字段')).filter(聚合字段別名條件).values('取分組字段', '取聚合字段別名')
# 規則:
1.values(...).annotate(...)為分組組合,values控制分組字段,annotate控制聚合字段
2.values可按多個字段分組values('分組字段1', ..., '分組字段n'),??如果省略代表按操作表的主鍵分組
3.可以同時對多個字段進行聚合處理annotate(別名1=聚合函數1('字段1'), ..., 別名n=聚合函數n('字段n'))
4.分組后的的filter代表having判斷,只對聚合字段進行條件判斷,可以省略(對非聚合字段或分組字段進行條件判斷代表where判斷)
5.取字段值values(...)省略默認取所有分組字段與聚合字段,也可以自主取個別分組字段及聚合字段(取字段的values中出現了非分組或非聚合字段,該字段自動成為分組字段)
# 案例:每個出版社出版的最貴的書的價格高于50元的出版社名與最高價格
Book.objects.all().values('publish__name').annotate(high_price=Max('price')).filter(high_price__gt=50).values('publish__name', 'high_price')
五 常用共有字段屬性
1. null:默認為False,True表示字段可為null
2. blank:默認為False,True表示字段可為空
3. choice:可選的,限制了該選項的字段值必須是所指定的choice中的一個:
-- sex = models.SmallIntegerField(choices=((1, '男'), (2, "女")))
-- obj.get_sex_display()
4. db_column:自定義字段名
5. db_index:如果為True的話,設置索引
6. default:字段默認值
7. editable:默認為True,若為False,則不會在/admin/界面顯示
8. primary_key:若設置為True,則表示將該字段設置為主鍵。一般情況下django默認會設置一個自增長的id主鍵。
9. unique:若設置為True,該字段值不可重復
六 常用字段
1. AutoField():默認自增主鍵(primary_key=True),django會默認建立id字段主鍵
2. BooleanField():布爾字段,對應數據庫tinyint類型
3. CharField():字符類型
-- 字段屬性max_length=64,數據長度,必須明確
4. DateField():年月日時間類型
-- 字段屬性auto_now=True,數據被更新就會更新時間
-- 字段屬性auto_now_add=True,數據第一次參數時產生
5. DateTimeField():年月日小時分鐘秒時間類型
-- 字段屬性auto_now=True,數據被更新就會更新時間
-- 字段屬性auto_now_add=True,數據第一次參數時產生
6. DecimalField():混合精度的小數類型
-- 字段屬性max_digits=3,限定數字的最大位數(包含小數位)
-- 字段屬性decimal_places=2,限制小數的最大位數
7. IntegerField():整型
七 不常用字段
1. BigAutoField():大整型自增
2. BigIntegerField():長整型
3. EmailField():郵箱字段,擁有/admin/驗證
4. FloatField():浮點型小數
5. SmallIntegerField():小整型
6. TextField():大文本類型
7. FileField():文件字段
八 關系字段
1. ForeignKey():外鍵字段
-- 字段屬性to關聯模型類
-- 字段屬性to_field關聯字段,省略默認關聯主鍵
-- 字段屬性on_delete (外鍵關聯數據被刪除時的操作)
-- models.CASCADE 級聯刪除
-- modles.PROTECT 拋出異常
-- models.SET_NULL 設置空值
-- models.SET_DEFAULT 設置默認值
-- models.SET(value)自定義值
-- 字段屬性related_name自定義反向查詢的字段名
-- 字段屬性db_constraint=False取消關聯關系,但還可以使用連表查詢
總結:models.ForeignKey(to='關聯的類名', null=True, on_delete=models.SET_NULL, db_constraint=False, related_name="本類名小寫")
2、OneToOneField():一對一外鍵字段
-- 字段同外鍵
3、ManyToManyField():多對多關系字段
-- 字段屬性to關聯模型類
-- 字段屬性through關聯關系類
-- 字段屬性through_fields關聯關系表中(本身類名小寫字段, 關聯表類名小寫字段)
九 斷開外鍵關聯的ForeignKey使用
# 1、不使用ForeignKey方式斷開關聯,不再支持Django ORM連表查詢語法
class Publish(models.Model):
name = models.CharField(max_length=20)
class Book(models.Model):
name = models.CharField(max_length=20)
# 字段需要寫_id來表示相關表的字段信息
publish_id = models.IntegerField()
# *****
# 2、使用ForeignKey方式用db_constraint=False字段屬性斷開關聯,依然支持Django ORM連表查詢語法,建議使用
class Publish(models.Model):
name = models.CharField(max_length=20)
class Book(models.Model):
name = models.CharField(max_length=20)
# 字段不需要寫_id來表示相關表的字段信息,ORM會自動添加
publish = models.ForeignKey(to='Publish', null=True, on_delete=models.SET_NULL, db_constraint=False)
十 斷開關聯的多對多自動創建關系表
# 使用ManyToManyField方式用db_constraint=False字段屬性斷開關聯,依然支持Django ORM連表查詢語法,建議使用
class MyBook(models.Model):
name = models.CharField(max_length=20)
my_author = models.ManyToManyField(to='MyAuthor', db_constraint=False)
class MyAuthor(models.Model):
name = models.CharField(max_length=20)
十一 斷開關聯的多對多手動創建關系表
# 手動創建關系表可以讓關系表可以擁有更多的自身的字段,同時通過關系表類名可以直接獲取第三張表
# 1、和自動建立關系表類似,依然支持Django ORM連表查詢語法(多對多借助關系表連表查詢)
class Book(models.Model):
name = models.CharField(max_length=20)
class Author(models.Model):
name = models.CharField(max_length=20)
class Book_Author(models.Model):
book = models.ForeignKey(to="Book", null=True, on_delete=models.SET_NULL, db_constraint=False)
author = models.ForeignKey(to='Author', null=True, on_delete=models.SET_NULL, db_constraint=False)
time = models.DateField()
# *****
2、手動創建關系表,用ManyToManyField方式支持正向反向ORM連表查詢,需要用db_constraint=False斷開關聯
-- to:多對多的關聯類
-- through:手動建立的關系表
-- through_fields:('關系表中代表本類的字段名', '關系表中代表關聯類的字段名')
class Book(models.Model):
name = models.CharField(max_length=20)
author = models.ManyToManyField(to='Author', through='Book_Author', through_fields=('book_id', 'author_id'), db_constraint=False)
class Author(models.Model):
name = models.CharField(max_length=20)
class Book_Author(models.Model):
book_id = models.IntegerField()
author_id = models.IntegerField()
time = models.DateField()
3、手動創建關系表,在關系表中用ForeignKey方式支持基于外鍵關系表的ORM連表查詢,同時明確ManyToManyField字段,所以也支持ORM正向方向連表查詢
-- db_constraint=False斷開關聯可以在ForeignKey或ManyToManyField任意一方完成
class Book(models.Model):
name = models.CharField(max_length=20)
# 明確through與through_fields,ManyToManyField才不會自動建立關系表
author = models.ManyToManyField(to='Author', through='Book_Author', through_fields=('book_id', 'author_id'), db_constraint=False)
class Author(models.Model):
name = models.CharField(max_length=20)
class Book_Author(models.Model):
book = models.ForeignKey(to="Book", null=True, on_delete=models.SET_NULL, db_constraint=False)
author = models.ForeignKey(to='Author', null=True, on_delete=models.SET_NULL, db_constraint=False)
time = models.DateField()
# 總結:手動創建第三張表,第三張表的增刪改就采用關系表類名衍生的create|delete|update,就不再擁有add|clear|remove|set(因為關系表擁有自己的字段,這些方法無法直接操作這些字段)
學習,學習,學習!
學習是為了更好的未來,不要讓別人瞧不起你,加油!??!
總結
- 上一篇: 抽油烟机包起来的利弊(汉典抽字的基本解释
- 下一篇: Linux ubi子系统原理分析