[英]Custom aggregate function in PostgreSQL
通過在當前值(列中的第一個值)中減去初始值(列中的最后一個值),是否可以在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返回最新條目的等級(按時間戳記)-最舊條目的等級(按時間戳記)
謝謝!
您可以在Postgres中使用JOIN和DISTINCT ON來實現。 GRP
查詢會為您提供每個userID
的最新rank
值,因此只需將其與user_id
上的rankings
和減去值一起加入即可。
SELECT rankings.userId,
rankings.rank-GRP.rank as delta,
rankings.timestamp
FROM rankings
JOIN
(
SELECT DISTINCT ON (userId) userId, rank, timestamp
FROM rankings
ORDER BY userId, timestamp DESC
) as GRP ON rankings.userId=GRP.userId
最新條目的排名(按時間戳記)-最舊條目的排名(按時間戳記)
現有功能可以通過多種方式實現。 您可以使用現有的窗口函數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)
,否則您的需求將是模棱兩可的。
... 又名“ 7武士”
注釋中的每個請求, 每個用戶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
僅為最新條目選擇結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.