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单表查询,跨表查询,分组查询相关推荐

  1. Django ORM – 多表实例(聚合与分组查询)

    聚合查询(aggregate) 聚合查询函数是对一组值执行计算,并返回单个值. 聚合查询返回值的数据类型是字典. 聚合函数 aggregate() 是 QuerySet 的一个终止子句, 生成的一个汇 ...

  2. oracle数据库怎么分组查询,oracle数据库之分组查询

    本章内容和大家分享的是数据当中的分组查询.分组查询复杂一点的是建立在多张表的查询的基础之上,(我们在上一节课的学习中已经给大家分享了多表查询的使用技巧,大家可以自行访问:多表查询1  多表查询2)而在 ...

  3. Python之Pandas:利用Pandas函数实现对表格文件的查之高级查询(类似sql,分组查询等)之详细攻略

    Python之Pandas:利用Pandas函数实现对表格文件的查之高级查询(类似sql,分组查询等)之详细攻略 目录 利用Pandas函数实现对表格文件的查之高级查询(类似sql) 1.分组查询

  4. mysql查询每个用户第一条数据_MySQL数据库订单表按用户邮箱字段分组查询每个用户的第一条记录...

    程序开发或者一些数据统计时,在MySQL中使用GROUP BY分组是很常用的SQL语句.那么,如果如下的简单示例订单数据表,我们现需要使用GROUP BY分组后查询每个用户的第一个订单记录,应该如何实 ...

  5. sql 基础语法 创建数据库和数据表 数据增删改查 分组查询 子查询回顾

    参考链接: SQL教程 MySQL教程 一.创建数据库语法 --用master数据库 use master --判断数据库是否存在,若存在则删除 if exists (select * from sy ...

  6. Oracle笔记(六) 多表查询、统计函数及分组查询、子查询

    本次预计讲解的知识点 1. 多表查询的操作.限制.笛卡尔积的问题: 2. 统计函数及分组统计的操作: 3. 子查询的操作,并且结合限定查询.数据排序.多表查询.统计查询一起完成各个复杂查询的操作: 一 ...

  7. mysql的查询、子查询、连接查询、groud by分组查询

    一.mysql查询的五种子句 where(条件查询).having(筛选).group by(分组).order by(排序).limit(限制结果数)  1.where常用运算符: 比较运算符 &g ...

  8. 一、MySQL查询学习笔记(基础查询、条件查询、排序查询、常见函数、分组查询 详解)

    DQL语言的学习 一.基础查询 语法: **SELECT 要查询的东西 [FROM 表名];**类似于Java中 :System.out.println(要打印的东西); 特点: ①通过select查 ...

  9. mysql怎么分组查询所有数据库_Mysql-4 分组查询与子查询

    1.查询结果的分组操作 a.分组允许把数据分为多个组,以便能对每个组进行聚集计算 b.分组是在select语句的group by 子句中建立的 注意:group by 只是创建分组,但并不保证分组里面 ...

  10. MySQL查询的进阶操作--分组查询

    目录 分组查询介绍 案例 一般案例 添加筛选条件的案例 分组后添加筛选条件案例 按表达式或函数分组案例 按多个字段分组案例 添加排序案例 分组查询介绍 3.group by 子句支持单个字段分组,多个 ...

最新文章

  1. Deep TEN: Texture Encoding Network
  2. 1057. 数零壹(20)
  3. spring的钩子_spring--BeanPostProcesstor
  4. Java反射原理学习之MethodHandle debug
  5. Android重点笔记,安卓listview 懒加载的实现笔记
  6. matlab迭代次数,怎么知道程序中的迭代次数呢
  7. python计算期望值_机器学习:计算方差时为何除以n-1
  8. 90后副教授一作发Science,刷新该校历史
  9. ASP.NET MVC 上传图片到项目目录中的文件夹并显示
  10. 前端:JS/19/特殊运算符,运算符优先级,if条件判断语句,switch分支语句,while循环语句,for循环语句,break和continue循环控制语句,实例:九九乘法表
  11. 继承(引用~析构~virtual)
  12. 分享一个前辈的NPOIhelper
  13. Android实战开发-Kotlin教程(语法篇 1.1)
  14. word如何绘制斜线表头
  15. 马斯克收购 Twitter 后的 Web3 改革方向
  16. 纺织服装产业实现智能制造升级
  17. 医疗检测产品设计规范有哪些?
  18. 聊天框 让滚动条保持到最底端的一种方式 scrollTop!
  19. 最新计算机java毕业设计选题题目推荐
  20. Spring Cloud Gateway 集成Sa-Token

热门文章

  1. 微服务配置中心是干啥的_配置中心微服务器配置
  2. 空间映射网络--Spatial Transformer Networks
  3. perf报错解决:no symbols found in /bin/dash, maybe install a debug package?和was updated (is prelink enabl
  4. C++ 虚函数个人理解
  5. java rhino js类_让Rhino JS看Java类
  6. python中立方_Python编程从入门到实践 第四章练习题
  7. yii mysql 事务处理_Yii2中事务的使用实例代码详解
  8. Azkaban入门(启动一个Simple Example)
  9. SpringBoot中使用rabbitmq
  10. html自动补全pspad,免费代码编辑器 PSPad Editor 5.0.4.541 中文多语免费版