既存の関数でこれを実現する方法はたくさんあります。既存の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)
を想定 、または要件があいまいになります。
七人の侍
コメントのリクエストごとに、ユーザーIDごとの最後の7行についてのみ同じです。 (または、少ない場合はできるだけ多く):
繰り返しますが、多くの可能な方法の1つです。しかし、これは最も短いものの1つだと思います:
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
を使用して最新のエントリの結果のみを選択します。 。