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