SQLalchemy去重,按不同列排序

4
我将使用SQLalchemy查询两个表,希望在查询中使用distinct特性以获得唯一的客户ID集合。
以下是我的查询语句:
orders[n] = DBSession.query(Order).\
          join(Customer).\
          filter(Order.oh_reqdate == date_q).\
          filter(Order.vehicle_id == vehicle.id).\
          order_by(Customer.id).\
          distinct(Customer.id).\
          order_by(asc(Order.position)).all() 

如果你能看到这里正在发生什么,我正在查询订单表格,以获取特定日期和车辆的所有订单,这很好用。但是,一些客户可能在同一天下了多个订单。因此,我试图将结果过滤为仅列出每个客户一次。这很好用,但是为了做到这一点,我必须首先按具有distinct()函数的列对结果进行排序。我可以添加第二个order_by到我想要的结果排序的列,而不会导致语法错误。但它被忽略了,结果仅按Customer.id排序。
由于外键的设置方式,我需要在Order表上执行查询并加入到客户端(而不是相反)。
我想做的事情是否可能在一个查询中完成?还是我需要重新循环我的结果以获得我想要的正确顺序的数据?
1个回答

3
您永远不需要“重新循环” - 如果您的意思是将行加载到Python中。您可能希望生成一个子查询并从中选择,这可以使用query.from_self().order_by(asc(Order.position))来实现。更具体的场景可以使用subquery()
在这种情况下,我真的无法确定您想要什么。如果客户拥有请求的车辆ID和日期的多个订单,则会获得两个行,每个订单行都将引用客户。您究竟想要什么?只需在每个客户组中获取第一张订单行吗?我会像这样做:
highest_order = s.query(Order.customer_id, func.max(Order.position).label('position')).\
                    filter(Order.oh_reqdate == date_q).\
                    filter(Order.vehicle_id == vehicle.id).\
                    group_by(Order.customer_id).\
                    subquery()

s.query(Order).\
    join(Customer).\
    join(highest_order, highest_order.c.customer_id == Customer.id).\
    filter(Order.oh_reqdate == date_q).\
    filter(Order.vehicle_id == vehicle.id).\
    filter(Order.position == highest_order.c.position)

啊,谢谢,这是一个更好的方法。我添加到s.query order_by(Order.position).all()中解决了它,使用两个查询是一个更好的想法。 - crooksey
尽管这解决了OP的特定问题,但当您想通过ID进行区分,但又要按另一列(比如客户姓氏)排序时,它并没有回答通用问题。 - jave.web
这个问题与SQLAlchemy无关,而是关于PostgreSQL的特殊“DISTINCT ON”语法。请提出一个新问题,仅涉及SQL,并将其标记为postgresql。 - zzzeek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接