所以,我试图创建一个查询,计数的数量重定向每周每个网站.我做了下面的查询,它给了我几乎正确的结果,但如果没有重定向,有没有计数结果(意味着没有0,没有,只是没有结果).我已经尝试把coalese外计数,但相同的结果.
当没有计数时,如何使此查询给予None或0?
date_series = db.func.generate_series(min_date , todays_date, timedelta(weeks=1))
trunc_date = db.func.date_trunc('week', date_series)
subquery = db.session.query(trunc_date.label('week')).subquery()
query = db.session.query(subquery.c.week, Site, db.func.count(db.func.coalesce(Redirect.id, 0)))\
.outerjoin(Site, subquery.c.week == db.func.date_trunc('week', Redirect.timestamp))\
.outerjoin(Site, Redirect.site_id == Site.id)\
.group_by(subquery.c.week, Site.id)
counts = query.all()
字符串
编辑:
所以我淡化了我的查询,从分组中删除Site,将'week'换成'day',并尝试只为一个Site获得所需的结果。然而,它仍然不起作用,它给我的结果就像我在做一个连接,而不是一个outerjoin。我真的不明白为什么它不会给我0计数结果。
参见更新的查询:
query = db.session.query(subquery.c.day, db.func.count(Redirect.id))\
.outerjoin(Redirect, subquery.c.day == db.func.date(Redirect.timestamp))\
.filter(Redirect.site_id == 82)\
.group_by(subquery.c.day)
型
它仍然只在有值的日子里给我结果:
0:(datetime.datetime(2022, 11, 23, 0, 0), 1)
1:(datetime.datetime(2023, 12, 7, 0, 0), 1)
型
生成的SQL:
SELECT anon_1.day AS anon_1_day, count(redirect.id) AS count_1
FROM (SELECT date_trunc(%(date_trunc_1)s, generate_series(%(generate_series_1)s, %(generate_series_2)s, %(generate_series_3)s)) AS day) AS anon_1 LEFT OUTER JOIN redirect ON anon_1.day = date(redirect.timestamp)
WHERE redirect.site_id = %(site_id_1)s GROUP BY anon_1.day
型
2条答案
按热度按时间30byixjq1#
您当前的查询使用的是outerjoin,这是正确的,可以确保包含date_series中的所有日期,即使没有相应的Redirect记录。但是,您计算Redirect.id的方式可能需要稍微调整。
相反,您应该直接计算Redirect.id,如果没有非空的Redirect.id值(由于outerjoin而没有匹配的Redirect记录时就是这种情况),count()函数将返回0。
像这样修改你的查询:
字符串
这个查询现在应该正确计算每周和每个站点的Redirect.id的数量,当没有匹配的重定向记录时返回0。
rqcrx0a62#
我想我知道了。
初始子查询与我在问题中显示的子查询相同,只是我每周都在更改。
现在看起来像这样:
字符串
然后我必须做第二个子查询来生成第一个子查询和Site中的日期之间的叉积,这意味着这两个日期的所有可能组合。我无法在初始子查询中生成叉积,因为它一直抱怨它无法进行连接。
下面是一个cross product query:
型
然后,我可以使用它来加入重定向的计数,方法是在date和site_id上进行外加入。
查询如下所示:
型
这现在给了我计数为每一天,每个网站,与0的地方没有重定向记录。