我有一张表,上面有影响者和他们每天的追随者:
influencer_id | date | followers
1 | 2020-05-29 | 7361
1 | 2020-05-28 | 7234
...
2 | 2020-05-29 | 82
2 | 2020-05-28 | 85
...
3 | 2020-05-29 | 3434
3 | 2020-05-28 | 2988
3 | 2020-05-27 | 2765
...
假设我想计算每个影响者在过去7天内获得了多少追随者,并得到下表:
influencer_id | growth
1 | <num followers last day - num followers first day>
2 | "
3 | "
作为第一次尝试,我这样做了:
SELECT influencer_id,
(MAX(followers) - MIN(followers)) AS growth
FROM influencer_follower_daily
WHERE date < '2020-05-30'
AND date >= '2020-05-23'
GROUP BY influencer_id;
这是有效的,并显示了每一个影响者在一周内的增长。但它假设追随者的数量总是增加,人们永远不会放弃!
那么,有没有一种方法可以在原始表上使用sql查询来实现我想要的呢?或者我必须使用 FOR
计算每个日期之间的+/-更改列的循环?
2条答案
按热度按时间mctunoxg1#
简单聚合函数
first()
以及last()
在标准postgres中没有实现。但见下文。1. 数组\u agg()
戈登演示了一个问题
array_agg()
,但这比必要的成本更高,尤其是对于每个组有许多行的情况。更重要的是,打了两次电话ORDER BY
每个骨料。这种等效的替代方法应该更快:因为它一次分类,一次聚合。内部子查询的排序顺序
sub1
被带入下一个层次。请参见:如何将order by和limit与聚合函数结合使用?
索引很重要:
如果查询整个表或其中大部分,则
(influencer_id, date, followers)
可以帮助(很多)索引只扫描。如果只查询表的一小部分,则
(date)
或者(date, influencer_id, followers)
我能帮上忙(很多)。2. 不同窗口函数(&W)
戈登还展示了
DISTINCT
具有窗口功能。同样,可以大大加快:使用单个窗口函数,使用相同的排序顺序(!)作为主查询。为了实现这一点,我们需要使用
ROWS BETWEEN ...
请参见:每行具有最大和最小日期加上关联id的postgresql查询
以及
DISTINCT ON
而不是DISTINCT
. 请参见:按组选择每组中的第一行?
3. 自定义聚合函数
first()和last()
你可以自己加,很简单。请参阅postgres wiki中的说明。
或安装附加模块
first_last_agg
在c语言中实现得更快。相关:
使用类似top和group by的方法
然后您的查询变得更简单:
自定义聚合增长()
你可以合并
first()
以及last()
在单个聚合函数中。这会更快,但是调用两个c函数仍然会比一个自定义sql函数的性能更好。基本上将我的第一个查询的逻辑封装在自定义聚合中:
适用于任何数字类型(或带有运算符的任何类型)
type - type
返回相同类型)。查询更简单,但:或者稍微慢一点,但最终很短:
db<>在这里摆弄
4. 每组多行的性能优化
对于每个组/分区有许多行的情况,其他查询技术可以更快(很多)。这些技巧:
按查询优化分组以检索每个用户的最新行
如果适用的话,我建议您开始一个新的问题,公开确切的表定义和基数。。。
密切相关:
从每组的第一行和最后一行获取值
postgresql:在group by子句中连接数组
使用类似top和group by的方法
对分组列中的重复值进行采样的最佳性能
disho6za2#
postgres没有
first()
/last()
聚合函数。一种方法是:另一种选择是使用数组: