zoukankan      html  css  js  c++  java
  • 聚合查询

    一 分组查询概念
        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(因为关系表拥有自己的字段,这些方法无法直接操作这些字段)
    学习,学习,学习! 学习是为了更好的未来,不要让别人瞧不起你,加油!!!
  • 相关阅读:
    UITextField最大字符数和最大字节数的限制
    Python profiling
    Glow Android 优化实践
    当 NSDictionary 遇见 nil
    TCP/IP详解2 学习笔记---mbuf
    行业代码获取最近代码
    词语、句子相似度比较
    从word得到表格数据插入数据库(6位行业代码)
    python遍历数组获取下标
    计算机浮点数表示
  • 原文地址:https://www.cnblogs.com/yangyufeng/p/10493376.html
Copyright © 2011-2022 走看看