排序和查询高级

排序和查询高级

  • 排序

    • 1、order_by:可以指定根据这个表中的某个字段进行排序,如果在前面加了一个-,代表的是降序排序。
    • 2、在模型定义的时候指定默认排序:有些时候,不想每次在查询的时候都指定排序的方式,可以在定义模型的时候就指定排序的方式。
      • 在模型定义中,添加以下代码
         __mapper_args__ = {
             "order_by": title
         }
        
      • 即可让文章使用标题来进行排序。
    • 3、正向排序和反向排序:默认情况是从小到大,从前到后排序的,如果想要反向排序,可以调用排序的字段的desc方法。
  • limit、offset和切片

    • limit:可以限制每次查询的时候只查询几条数据。
    • offset:可以限制查找数据的时候过滤掉前面多少条。
    • 切片:可以对Query对象使用切片操作,来获取想要的数据。
  • 查询高级

    • group_by

      根据某个字段进行分组。比如想要根据性别进行分组,来统计每个分组分别有多少人

      session.query(User.gender,func.count(User.id)).group_by(User.gender).all()
      
    • having

      having是对查找结果进一步过滤。比如只想要看未成年人的数量,那么可以首先对年龄进行分组统计人数,然后再对分组进行having过滤。

      result = session.query(User.age,func.count(User.id)).group_by(User.age).having(User.age >= 18).all()
      
    • join方法

      join查询分为两种,一种是inner join,另一种是outer join。默认的是inner join,如果指定left join或者是right join则为outer join。如果想要查询User及其对应的Address,则可以通过以下方式来实现

      for u,a in session.query(User,Address).filter(User.id==Address.user_id).all():
          print(u)
          print(a)
      

      这是通过普通方式的实现,也可以通过join的方式实现,更加简单

      for u,a in session.query(User,Address).join(Address).all():
          print(u)
          print(a)
      

      当然,如果采用outerjoin,可以获取所有user,而不用在乎这个user是否有address对象,并且outerjoin默认为左外查询:

      for instance in session.query(User,Address).outerjoin(Address).all():
      	print(instance)
      
  • 别名:

    当多表查询的时候,有时候同一个表要用到多次,这时候用别名就可以方便的解决命名冲突的问题了:

    from sqlalchemy.orm import aliased
    adalias1 = aliased(Address)
    adalias2 = aliased(Address)
    for username,email1,email2 in session.query(User.name,adalias1.email_address,adalias2.email_address).join(adalias1).join(adalias2).all():
        print(username,email1,email2)
    
  • 子查询

    sqlalchemy也支持子查询,比如现在要查找一个用户的用户名以及该用户的邮箱地址数量。要满足这个需求,可以在子查询中找到所有用户的邮箱数(通过group by合并同一用户),然后再将结果放在父查询中进行使用:

    from sqlalchemy.sql import func
    # 构造子查询
    stmt = session.query(Address.user_id.label('user_id'),func.count(*).label('address_count')).group_by(Address.user_id).subquery()
    # 将子查询放到父查询中
    for u,count in session.query(User,stmt.c.address_count).outerjoin(stmt,User.id==stmt.c.user_id).order_by(User.id):
        print u,count
    

    从上面我们可以看到,一个查询如果想要变为子查询,则是通过subquery()方法实现,变成子查询后,通过子查询.c属性来访问查询出来的列。以上方式只能查询某个对象的具体字段,如果要查找整个实体,则需要通过aliased方法

    stmt = session.query(Address)
    adalias = aliased(Address,stmt)
    for user,address in session.query(User,stmt).join(stmt,User.addresses):
    print user,address
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值