通过在当前值(列中的第一个值)中减去初始值(列中的最后一个值),是否可以在PostgreSQL中编写一个聚合函数来计算增量值?它将适用于这样的结构
rankings (userId, rank, timestamp)
并且可以像
SELECT userId, custum_agg(rank) OVER w FROM rankings WINDOWS w AS (PARTITION BY userId ORDER BY timstamp desc)
为userId返回最新条目的等级(按时间戳记)-最旧条目的等级(按时间戳记)
谢谢!
最新条目的排名(按时间戳记)-最旧条目的排名(按时间戳记)
现有功能可以通过多种方式来实现。您可以使用现有的窗口函数first_value()和last_value(),将其与DISTINCT或结合使用DISTINCT ON,而无需联接和子查询:
first_value()
last_value()
DISTINCT
DISTINCT ON
SELECT DISTINCT ON (userid) userid , last_value(rank) OVER w - first_value(rank) OVER w AS rank_delta FROM rankings WINDOW w AS (PARTITION BY userid ORDER BY ts ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING);
注意窗口功能的自定义框架!
或者,您可以在子查询和JOIN中使用基本的聚合函数:
SELECT userid, r2.rank - r1.rank AS rank_delta FROM ( SELECT userid , min(ts) AS first_ts , max(ts) AS last_ts FROM rankings GROUP BY 1 ) sub JOIN rankings r1 USING (userid) JOIN rankings r2 USING (userid) WHERE r1.ts = first_ts AND r2.ts = last_ts;
假设唯一(userid, rank),否则您的要求将是不明确的。
(userid, rank)
SQL Fiddle。
…也称为“ 7 Samurai”, 每个请求在注释中, 每个用户ID 仅适用于 最后七个行 (如果有更少,则可以找到尽可能多的 行 ):
同样,许多可能的方式之一。但我认为这是最短的方法之一:
SELECT DISTINCT ON (userid) userid , first_value(rank) OVER w - last_value(rank) OVER w AS rank_delta FROM rankings WINDOW w AS (PARTITION BY userid ORDER BY ts DESC ROWS BETWEEN CURRENT ROW AND 7 FOLLOWING) ORDER BY userid, ts DESC;
请注意相反的排序顺序。第一行是“最新”条目。我跨过一帧(最多)7行,并仅使用来选择最新条目的结果DISTINCT ON。