基于每个组中的时间范围进行过滤sqlalchemy

问题描述

我有一个表,用于存储从已知数量的客户购买的所有商品。因此,每一行都包含客户的名称和所购买的商品以及购买时间。

实际上,我们可以找到每个客户进行的首次购买。

我想基于每个客户的购买时间对行进行排序,但有一个条件,即购买时间应为从首次购买该客户起至少2个月。

让我们在一个示例中进一步说明: (每个客户的购买按时间排序)

customer1 purchases: 2018/7/1,2018/8/2,2018/9/3,2019,9,4
customer2 purchases: 2019/10/10,2019/10/11,2019/10/12,11,11
...

对于客户1,如果我们要查找旧购买后两个月内的订单(即2018/7/1),我们将得到2018/9/3,4

对于客户2,最早的购买是2018/7/1,所以我们得到2019,11

基本上,对于每个客户,我要查找按时间排序的最旧购买至少两个月后的所有购买。

解决方法

假设您只想要购买日期,则可以使用汇总将它们添加到列表中。在Postgresql中,这类似于:

SELECT customer_id,ARRAY_AGG(date ORDER BY date)
FROM purchase
JOIN (
    SELECT customer_id,min(date) as date
    FROM purchases
    GROUP BY customer_id
) AS first_purchase ON first_purchase.customer_id = purchase.customer_id
WHERE purchase.date >= first_purchase.date + '2 MONTHS'::interval
GROUP BY customer_id

在SQLAlchemy中:

import sqlalchemy as sa
from sqlalchemy.dialects.postgresql import aggregate_order_by

first_purchase = sa.select([
  Purchase.customer_id,sa.func.max(Purchase.date).label('date')
]).group_by(Purchase.customer_id).subquery()

query = sa.select([
  Purchase.customer_id,sa.func.array_agg(aggregate_order_by(Purchase.date,Purchase.date))
]).select_from(
  Purchase.join(first_purchase,first_purchase.c.customer_id == Purchase.customer_id)
).where(
  Purchase.date >= first_purchase.c.date + sa.cast('2 MONTHS',sa.Interval)
).group_by(Purchase.customer_id)

请注意,两个查询的结构有多么相似

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...