ORM单表查询,跨表查询,分组查询
ORM单表查询,跨表查询,分组查询
单表查询之下划线
models.Tb1.objects.filter(id__lt=10, id__gt=1) # 获取id大于1 且 小于10的值models.Tb1.objects.filter(id__in=[11, 22, 33]) # 获取id等于11、22、33的数据models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in models.Tb1.objects.filter(name__contains="ven") # 获取name字段包含"ven"的models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感models.Tb1.objects.filter(id__range=[1, 3]) # id范围是1到3的,等价于SQL的bettwen and类似的还有:startswith,istartswith, endswith, iendswith date字段还可以:models.Class.objects.filter(first_day__year=2017)
#获取id大于1且小于10的值 print(models.Book.objects.filter(id__lt=10,id__gt=1)) # 查询 id 在 [1, 4, 5, 7]中的结果 print(models.Book.objects.filter(id__in=[1,4,5,7])) # contains 字段包含指定值的 print(models.Book.objects.filter(title__contains="小单")) # icontains 忽略大小写包含指定值 print(models.Book.objects.filter(title__icontains="NI")) # 判断id值在 哪个区间的 SQL语句中的between and 1<= <=3 print(models.Book.objects.filter(id__range=[1,3])) # 日期和时间字段还可以有以下写法 ret = models.Person.objects.filter(birthday__year=2000) ret = models.Person.objects.filter(birthday__year=2000, birthday__month=5)
跨表查询操作
class Author(models.Model):nid = models.AutoField(primary_key=True)name=models.CharField( max_length=32)age=models.IntegerField()# 与AuthorDetail建立一对一的关系authorDetail=models.OneToOneField(to="AuthorDetail",on_delete=models.CASCADE)class AuthorDetail(models.Model):nid = models.AutoField(primary_key=True)birthday=models.DateField()telephone=models.BigIntegerField()addr=models.CharField( max_length=64)class Publish(models.Model):nid = models.AutoField(primary_key=True)name=models.CharField( max_length=32)city=models.CharField( max_length=32)email=models.EmailField() class Book(models.Model):nid = models.AutoField(primary_key=True)title = models.CharField( max_length=32)publishDate=models.DateField()price=models.DecimalField(max_digits=5,decimal_places=2)# 与Publish建立一对多的关系,外键字段建立在多的一方publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE)# 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表authors=models.ManyToManyField(to='Author',)
View Code
基于对象查询(子查询)
按字段(publish) 一对多 book -----------------> publish <---------------- book_set.all()
正向查询按字段:查询python这本书籍的出版社的邮箱python=models.Book.objects.filter(title="python").first()print(python.publish.email)反向查询按 表名小写_set.all()苹果出版社出版的书籍名称publish_obj=models.Publish.objects.filter(name="苹果出版社").first()for obj in publish_obj.book_set.all():print(obj.title)
按字段(authors.all()) 多对多 book -----------------------> author <---------------------- book_set.all()
查询python作者的年龄python = models.Book.objects.filter(title="python").first()for author in python.authors.all():print(author.name ,author.age)查询alex出版过的书籍名称alex=models.Author.objects.filter(name="alex").first()for book in alex.book_set.all():print(book.title)
按字段 authorDetail 一对一 author -----------------------> authordetail <---------------- 按表名 author
查询alex的手机号alex=models.Author.objects.filter(name='alex').first()print(alex.authorDetail.telephone)查询家在山东的作者名字ad_list=models.AuthorDetail.objects.filter(addr="shandong")for ad in ad_list:print(ad.author.name)对应的sql:select publish_id from Book where title="python"select email from Publish where nid = 1
基于queryset和__查询(join查询)
正向查询:按字段 反向查询:表名小写 查询python这本书籍的出版社的邮箱ret=models.Book.objects.filter(title="python").values("publish__email")print(ret.query) select publish.email from Book left join Publish on book.publish_id=publish.nid where book.title="python" 苹果出版社出版的书籍名称方式1:ret1 = models.Publish.objects.filter(name="苹果出版社").values("book__title")print("111111111====>", ret1.query)# 方式2:ret2 = models.Book.objects.filter(publish__name="苹果出版社").values("title")print("2222222222====>", ret2.query) 查询alex的手机号方式1:ret = models.Author.objects.filter(name="alex").values("authorDetail__telephone") 方式2:models.AuthorDetail.objects.filter(author__name="alex").values("telephone") 查询手机号以151开头的作者出版过的书籍名称以及书籍对应的出版社名称 ret = models.Book.objects.filter(authors__authorDetail__telephone__startswith="151").values('title', "publish__name")print(ret.query)
# 1.正向查询 基于对象 跨表查询 book_obj = models.Book.objects.all().first() #对象 ret = book_obj.publisher # 和我这本书关联的出版社对象 print(ret, type(ret)) ret = book_obj.publisher.name # 和我这本书关联的出版社对象 print(ret, type(ret)) # 2.利用双下划线 跨表查询 双下划线就表示跨了一张表,基于Queryset ret = models.Book.objects.filter(id=1).values_list("publisher__name") print(ret) #等同于 print( models.Book.objects.all().first().publisher.name) print("反向查询".center(80, "*")) # 反向查询 1. 基于对象查询 publisher_obj = models.Publisher.objects.get(id=1) # 得到一个具体的对象 # ret = publisher_obj.book_set.all() #表名_set ret = publisher_obj.books.all() #如果设置了related_name="books" print(ret) # 2. 基于双下划线 基于Queryset ret = models.Publisher.objects.filter(id=1).values_list("book__title") print(ret)
View Code
聚合查询
aggregate()是QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。用到的内置函数:from django.db.models import Avg, Sum, Max, Min, Countfrom django.db.models import Avg, Sum, Max, Min, Countbook_obj=models.Book.objects.all()print(book_obj.aggregate(Max("price"))) #{'price__max': Decimal('9999.99')}#指定一个名称print(book_obj.aggregate(max_price=Max("price"))) #{'max_price': Decimal('9999.99')}#生成多个聚合print(book_obj.aggregate(Max("price"),Min("price"),Avg("price"))) #{'price__max': Decimal('9999.99'), 'price__min': Decimal('10.00'), 'price__avg': 1507.141429}
分组查询
1.和sql对比: 1.models.Employee Employee相当于sql中的from 后面的表名 2.annotate前面的values值相当于group by的字段 3.(a=Avg("salary"))里面如是跨表查询就需要使用双下划线,正查就字段__另一张表的字段,反查就另一张表明__字段 4.annotate后面的values 是select的字段 对应格式:select __ from ___ inner join ———— on ... group by ____2.关键点: 1.queryset对象.annotate() annotate前面是queryset对象 2.annotate进行分组统计,按前面select的字段进行group by 3.annotate()返回值依然是queryset对象,增加了分组统计之后的键值对
1.ORM中values或者values_list 里面写什么字段,就相当于select 什么字段ORM分组查询 每个部门名称及部门的平均年龄 ret = models.Employee.objects.all().values("dept", "age") SQL语句 """ SELECT `employee`.`dept`, `employee`.`age` FROM `employee` LIMIT 21; args=() """ 2.ORM中 annotate 前面是什么就按照什么分组 from django.db.models import Avg ret = models.Employee.objects.values("province").annotate(a=Avg("salary")).values("province", "a") 相当于: SELECT `employee`.`province`, AVG(`employee`.`salary`) AS `a` FROM `employee` GROUP BY `employee`.`province` ORDER BY NULL LIMIT 21; args=() print("分组查询".center(80, "*")) 3. ORM跨表分组查询,queryset对象跨表查询时使用双下划线 ret = models.Person.objects.values("dept_id").annotate(a=Avg("salary")).values("dept__name", "a") 反向: """ SELECT `dept`.`name`, AVG(`person`.`salary`) AS `a` FROM `person` INNER JOIN `dept` ON (`person`.`dept_id` = `dept`.`id`) GROUP BY `person`.`dept_id`, `dept`.`name` ORDER BY NULL LIMIT 21; args=() """ 4.查询每一个部门的名称和人数 #正向查询: models.emp.objects.values("dept_id").annotate(c=Count("name")).values("dept__name","c") #反向查询 models.dep.objects.values("name").annotate(c=Count("emp__name")).values("name","c") SQL: select dep_name Count(emp.name) from emp inner join dep on .... group by dep_id5.查询每一个作者的名字及出版过的书籍的最高价 models.Author.objects.values('id').annotate(c=Max('book__price')).values("name","c") ##多对多的关系,在sql中跨了多张表 select __ from author inner join book_authors on .... inner join ... group by author.name 6.查询每一本书作者的个数 models.Book.objects.values("id").annotate(c=Count("authors__name")).values("title","c")
ret=models.Book.objects.all().annotate(author_num=Count("author")) for book in ret:print("书名:{},作者数量:{}".format(book.title, book.author_num))
#查询每一个分类的名称及对应的文章数 models.Category.objects.values("id").annotate(c=Count("article__title")).values("title","c") 7.统计不止一个作者的图书(过滤完后显示) models.Book.objects.values("title").annotate(c=Count("authors__name")).filter(c__gt=1).values('name',"c") 8.查询各个作者出的书的总价格 ret = models.Author.objects.all().annotate(price_sum=Sum("books__price")) for i in ret: print(i, i.name, i.price_sum)
extra --> 在执行ORM查询的时候执行额外的SQL语句
# 查询person表,判断每个人的工资是否大于2000 ret = models.Person.objects.all().extra(select={"gt": "salary > 2000"} ) 相当于: SELECT (salary > 2000) AS `gt`, `person`.`id`, `person`.`name`, `person`.`salary`, `person`.`dept_id` FROM `person` LIMIT 21; args=()
直接执行原生的SQL语句,类似pymysql的用法
from django.db import connection cursor = connection.cursor() # 获取光标,等待执行SQL语句 cursor.execute("""SELECT * from person where id = %s""", [1]) row = cursor.fetchone() print(row)
F查询和Q查询 F查询
要对两个字段的值做比较,Django 提供 F() 来做这样的比较。 F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。 1.查询评论数大于收藏数的书籍 from django.db.models import F models.Book.objects.filter(commnet_num__gt=F('keep_num')) 2.Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作。 models.Book.objects.filter(commnet_num__lt=F('keep_num')*2) 3修改操作也可以使用F函数,比如将每一本书的价格提高30元 # 具体的对象没有update(),QuerySet对象才有update()方法 models.Book.objects.all().update(price=F("price")+30) 刷单 把每一本书的卖出数都乘以3 obj = models.Book.objects.first() obj.maichu = 1000 * 3 obj.save() 4.给每一本书的书名后面加上 第一版 from django.db.models.functions import Concat from django.db.models import Value models.Book.objects.update(title=Concat(F("title"), Value("第一版")))
Q查询
如果你需要执行更复杂的查询(例如OR语句),你可以使用Q对象。 from django.db.models import Q 1.查询 卖出数大于1000,并且 价格小于100的所有书 ret = models.Book.objects.filter(maichu__gt=1000, price__lt=100) print(ret) 2.查询 卖出数大于1000,或者 价格小于100的所有书 ret = models.Book.objects.filter(Q(maichu__gt=1000) | Q(price__lt=100)) 3. Q查询和字段查询同时存在时, 字段查询要放在Q查询的后面 ret = models.Book.objects.filter(Q(maichu__gt=1000) | Q(price__lt=100), title__contains="金老板")
Q().children查询
Q().children,通过字段字符串查询q=Q()##查询出title字段中值为go的对象q.children.append(("title","go"))Book.objects.filter(q)Out[11]: <QuerySet [<Book: go>]>##查询出title字段中值含有g的对象q.children.append(("title__contains","g"))Book.objects.filter(q)Out[13]: <QuerySet [<Book: go>]>q=Q() #不同的字段之间的关系默认为andq.children.append(("title__contains","g"))q.children.append(("price",100))Book.objects.filter(q)Out[17]: <QuerySet []>q=Q()q.connector="or" #不同的字段之间的关系更改为orq.children.append(("title__contains","g"))q.children.append(("price",100))Book.objects.filter(q)Out[22]: <QuerySet [<Book: go>]>
转载于:https://www.cnblogs.com/FWF1944/p/10859301.html
ORM单表查询,跨表查询,分组查询相关推荐
- Django ORM – 多表实例(聚合与分组查询)
聚合查询(aggregate) 聚合查询函数是对一组值执行计算,并返回单个值. 聚合查询返回值的数据类型是字典. 聚合函数 aggregate() 是 QuerySet 的一个终止子句, 生成的一个汇 ...
- oracle数据库怎么分组查询,oracle数据库之分组查询
本章内容和大家分享的是数据当中的分组查询.分组查询复杂一点的是建立在多张表的查询的基础之上,(我们在上一节课的学习中已经给大家分享了多表查询的使用技巧,大家可以自行访问:多表查询1 多表查询2)而在 ...
- Python之Pandas:利用Pandas函数实现对表格文件的查之高级查询(类似sql,分组查询等)之详细攻略
Python之Pandas:利用Pandas函数实现对表格文件的查之高级查询(类似sql,分组查询等)之详细攻略 目录 利用Pandas函数实现对表格文件的查之高级查询(类似sql) 1.分组查询
- mysql查询每个用户第一条数据_MySQL数据库订单表按用户邮箱字段分组查询每个用户的第一条记录...
程序开发或者一些数据统计时,在MySQL中使用GROUP BY分组是很常用的SQL语句.那么,如果如下的简单示例订单数据表,我们现需要使用GROUP BY分组后查询每个用户的第一个订单记录,应该如何实 ...
- sql 基础语法 创建数据库和数据表 数据增删改查 分组查询 子查询回顾
参考链接: SQL教程 MySQL教程 一.创建数据库语法 --用master数据库 use master --判断数据库是否存在,若存在则删除 if exists (select * from sy ...
- Oracle笔记(六) 多表查询、统计函数及分组查询、子查询
本次预计讲解的知识点 1. 多表查询的操作.限制.笛卡尔积的问题: 2. 统计函数及分组统计的操作: 3. 子查询的操作,并且结合限定查询.数据排序.多表查询.统计查询一起完成各个复杂查询的操作: 一 ...
- mysql的查询、子查询、连接查询、groud by分组查询
一.mysql查询的五种子句 where(条件查询).having(筛选).group by(分组).order by(排序).limit(限制结果数) 1.where常用运算符: 比较运算符 &g ...
- 一、MySQL查询学习笔记(基础查询、条件查询、排序查询、常见函数、分组查询 详解)
DQL语言的学习 一.基础查询 语法: **SELECT 要查询的东西 [FROM 表名];**类似于Java中 :System.out.println(要打印的东西); 特点: ①通过select查 ...
- mysql怎么分组查询所有数据库_Mysql-4 分组查询与子查询
1.查询结果的分组操作 a.分组允许把数据分为多个组,以便能对每个组进行聚集计算 b.分组是在select语句的group by 子句中建立的 注意:group by 只是创建分组,但并不保证分组里面 ...
- MySQL查询的进阶操作--分组查询
目录 分组查询介绍 案例 一般案例 添加筛选条件的案例 分组后添加筛选条件案例 按表达式或函数分组案例 按多个字段分组案例 添加排序案例 分组查询介绍 3.group by 子句支持单个字段分组,多个 ...
最新文章
- Deep TEN: Texture Encoding Network
- 1057. 数零壹(20)
- spring的钩子_spring--BeanPostProcesstor
- Java反射原理学习之MethodHandle debug
- Android重点笔记,安卓listview 懒加载的实现笔记
- matlab迭代次数,怎么知道程序中的迭代次数呢
- python计算期望值_机器学习:计算方差时为何除以n-1
- 90后副教授一作发Science,刷新该校历史
- ASP.NET MVC 上传图片到项目目录中的文件夹并显示
- 前端:JS/19/特殊运算符,运算符优先级,if条件判断语句,switch分支语句,while循环语句,for循环语句,break和continue循环控制语句,实例:九九乘法表
- 继承(引用~析构~virtual)
- 分享一个前辈的NPOIhelper
- Android实战开发-Kotlin教程(语法篇 1.1)
- word如何绘制斜线表头
- 马斯克收购 Twitter 后的 Web3 改革方向
- 纺织服装产业实现智能制造升级
- 医疗检测产品设计规范有哪些?
- 聊天框 让滚动条保持到最底端的一种方式 scrollTop!
- 最新计算机java毕业设计选题题目推荐
- Spring Cloud Gateway 集成Sa-Token
热门文章
- 微服务配置中心是干啥的_配置中心微服务器配置
- 空间映射网络--Spatial Transformer Networks
- perf报错解决:no symbols found in /bin/dash, maybe install a debug package?和was updated (is prelink enabl
- C++ 虚函数个人理解
- java rhino js类_让Rhino JS看Java类
- python中立方_Python编程从入门到实践 第四章练习题
- yii mysql 事务处理_Yii2中事务的使用实例代码详解
- Azkaban入门(启动一个Simple Example)
- SpringBoot中使用rabbitmq
- html自动补全pspad,免费代码编辑器 PSPad Editor 5.0.4.541 中文多语免费版