SQL炼金术;计算一段时间内两个日期之间的项目



我的postgres DB有一个价格表,我在其中存储一堆产品的价格数据。对于创建时存储的每个Price对象(Price.timestamp(,每当产品有新价格时,我都会创建一个新的Price对象,对于结束时存储的旧Price对象来说(Price.end_time(。这两个时间都是日期时间对象。

现在,我想数一下一段时间内有多少价格。我觉得很简单,所以我做了下面的查询:

trunc_date = db.func.date_trunc('day', Price.timestamp)
query = db.session.query(trunc_date, db.func.count(Price.id))
query = query.order_by(trunc_date.desc())
query = query.group_by(trunc_date)
prices_count = query.all()

这很好,但只计算每天有多少价格是新的/创建的。所以我想我可以做的是过滤,这样我就可以得到trunc_date位于价格开始和结束之间的价格,如下所示:

query = query.filter(Price.timestamp < trunc_date < Price.time_ended)

但显然,您不允许以这种方式使用trunc_date。有人能帮我写查询吗?

数据示例:

Price.id    Price.timestamp    Price.time_ended
1           2022-18-09         2022-26-09
2           2022-13-09         2022-20-09

我想得到的查询结果是:

2022-27-09; 0
2022-26-09; 1
2022-25-09; 1
...
2022-20-09; 2
2022-19-09; 2
2022-18-09; 2
2022-17-09; 1
...
2022-12-09; 0

我想明白了。

首先,我使用子查询创建了一个日期范围。

todays_date = datetime.today() - timedelta(days = 1)
numdays = 360
min_date = todays_date - timedelta(days = numdays)
date_series = db.func.generate_series(min_date , todays_date, timedelta(days=1))
trunc_date = db.func.date_trunc('days', date_series)
subquery = db.session.query(trunc_date.label('day')).subquery()

然后,我在原始查询中使用子查询作为输入,最终能够从子查询中筛选日期。

query = db.session.query(subquery.c.day, db.func.count(Price.id))
query = query.order_by(subquery.c.day.desc())
query = query.group_by(subquery.c.day)
query = query.filter(Price.timestamp < subquery.c.day)
query = query.filter(Price.time_ended > subquery.c.day)

现在,query.all((将为您提供一个很好的列表,其中统计date_series中指定的每一天的价格。

您是否尝试过在过滤器内分离条件?

query = db.session.
query(trunc_date, db.func.count(Price.id)).
filter(
(Price.timestamp < trunc_date),
(trunc_date < Price.time_ended)
).
group_by(trunc_date).
order_by(trunc_date.desc()).
all()

您可以使用以下解决方案:

trunc_date.between(Price.timestamp, Price.time_ended)

最新更新