あなたはそうではありません 実際、集計関数を使用しています。 ウィンドウ関数を使用しています 。そのため、PostgreSQLはsp.payout
を要求します およびs.buyin
GROUP BY
に含まれる 条項。
OVER
を追加する 句、集計関数sum()
はウィンドウ関数に変換され、保持しながらパーティションごとに値を集計します。 すべての行。
ウィンドウ関数と集計関数を組み合わせることができます 。集計が最初に適用されます。あなたの説明から、イベントごとに複数のペイアウト/バイインをどのように処理したいかがわかりませんでした。推測として、私はイベントごとにそれらの合計を計算します。 今 sp.payout
を削除できます およびs.buyin
GROUP BY
から 句を使用して、player
ごとに1行を取得します およびevent
:
SELECT p.name
, e.event_id
, e.date
, sum(sum(sp.payout)) OVER w
- sum(sum(s.buyin )) OVER w AS "Profit/Loss"
FROM player p
JOIN result r ON r.player_id = p.player_id
JOIN game g ON g.game_id = r.game_id
JOIN event e ON e.event_id = g.event_id
JOIN structure s ON s.structure_id = g.structure_id
JOIN structure_payout sp ON sp.structure_id = g.structure_id
AND sp.position = r.position
WHERE p.player_id = 17
GROUP BY e.event_id
WINDOW w AS (ORDER BY e.date, e.event_id)
ORDER BY e.date, e.event_id;
この式の場合:sum(sum(sp.payout)) OVER w
、外側のsum()
はウィンドウ関数であり、内部のsum()
は集計関数です。
p.player_id
を想定 およびe.event_id
PRIMARY KEY
です それぞれのテーブルで。
e.event_id
を追加しました ORDER BY
へ WINDOW
の 決定論的なソート順に到達するための句。 (同じ日に複数のイベントが発生する可能性があります。)event_id
も含まれています 結果として、1日あたりの複数のイベントを区別します。
クエリはシングルに制限されますが プレーヤー(WHERE p.player_id = 17
)、p.name
を追加する必要はありません またはp.player_id
GROUP BY
へ およびORDER BY
。結合の1つが行を不当に乗算する場合、結果の合計は正しくありません(部分的または完全に乗算されます)。 p.name
によるグループ化 その場合、クエリを修復できませんでした。
e.date
も削除しました GROUP BY
から 句。主キーe.event_id
PostgreSQL9.1以降の入力行のすべての列をカバーしています。
もし 一度に複数のプレーヤーを返すようにクエリを変更し、適応させます:
...
WHERE p.player_id < 17 -- example - multiple players
GROUP BY p.name, p.player_id, e.date, e.event_id -- e.date and p.name redundant
WINDOW w AS (ORDER BY p.name, p.player_id, e.date, e.event_id)
ORDER BY p.name, p.player_id, e.date, e.event_id;
p.name
でない限り player_id
によって一意(?)、グループ、順序で定義されます さらに、決定論的なソート順で正しい結果を取得します。
e.date
のみを保持しました およびp.name
GROUP BY
で パフォーマンス上の利点を期待して、すべての句で同じソート順を持つようにします。それ以外の場合は、そこで列を削除できます。 (e.date
についても同様です 最初のクエリで。)