ギャップと島 のタグが付いた質問を表示する 確かに問題です。
想定:
- 「ストリーク」は他のプレイヤーからの列によって中断されません。
- すべての列が定義されています
NOT NULL
。 (それ以外の場合は、さらに多くのことを行う必要があります。)
これは、2つの高速 row_number()
ウィンドウ関数
:
SELECT DISTINCT ON (player_id)
player_id, count(*) AS seq_len, min(ts) AS time_began
FROM (
SELECT player_id, points, ts
, row_number() OVER (PARTITION BY player_id ORDER BY ts)
- row_number() OVER (PARTITION BY player_id, points ORDER BY ts) AS grp
FROM tbl
) sub
WHERE points = 100
GROUP BY player_id, grp -- omit "points" after WHERE points = 100
ORDER BY player_id, seq_len DESC, time_began DESC;
db <> fiddle こちら
列名ts
を使用する time
の代わりに 、これは予約語
です。 標準SQLで。 Postgresでは許可されていますが、制限があり、識別子として使用することは依然として悪い考えです。
「トリック」は、連続する行が同じグループに含まれるように行番号を減算することです(grp
)(player_id, points)
ごと 。 次に 100ポイントでフィルタリングし、グループごとに集計して、プレーヤーごとに最も長く最新の結果のみを返します。
テクニックの基本的な説明:
GROUP BY
を使用できます およびDISTINCT ON
同じSELECT
内 、GROUP BY
前に適用されます DISTINCT ON
。 SELECT
の一連のイベントについて考えてみましょう。 クエリ:
DISTINCT ON
について :