Je bent niet , in feite met behulp van geaggregeerde functies. U gebruikt vensterfuncties . Daarom eist PostgreSQL sp.payout en s.buyin op te nemen in de GROUP BY clausule.
Door een OVER . toe te voegen clausule, de aggregatiefunctie sum() wordt omgezet in een vensterfunctie, die waarden per partitie verzamelt terwijl behouden alle rijen.
U kunt vensterfuncties en aggregatiefuncties combineren . Aggregaties worden eerst toegepast. Ik begreep uit je beschrijving niet hoe je wilt omgaan met meerdere uitbetalingen/buy-ins per evenement. Als gok bereken ik een som hiervan per gebeurtenis. Nu Ik kan sp.payout verwijderen en s.buyin uit de GROUP BY clausule en krijg één rij per player en 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;
In deze uitdrukking:sum(sum(sp.payout)) OVER w , de buitenste sum() is een vensterfunctie, de binnenste sum() is een geaggregeerde functie.
Ervan uitgaande dat p.player_id en e.event_id zijn PRIMARY KEY in hun respectievelijke tabellen.
Ik heb e.event_id . toegevoegd naar de ORDER BY van het WINDOW clausule om tot een deterministische sorteervolgorde te komen. (Er kunnen meerdere evenementen op dezelfde datum zijn.) Ook event_id in het resultaat om meerdere gebeurtenissen per dag te onderscheiden.
Terwijl de zoekopdracht beperkt is tot een enkele speler (WHERE p.player_id = 17 ), hoeven we p.name niet toe te voegen of p.player_id naar GROUP BY en ORDER BY . Als een van de joins rijen onnodig zou vermenigvuldigen, zou de resulterende som onjuist zijn (gedeeltelijk of volledig vermenigvuldigd). Groeperen op p.name kon de query toen niet herstellen.
Ik heb ook e.date verwijderd uit de GROUP BY clausule. De primaire sleutel e.event_id omvat alle kolommen van de invoerrij sinds PostgreSQL 9.1.
Als je verandert de zoekopdracht om meerdere spelers tegelijk te retourneren, pas aan:
...
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;
Tenzij p.name wordt gedefinieerd als uniek (?), groep en volgorde door player_id bovendien om correcte resultaten te krijgen in een deterministische sorteervolgorde.
Ik heb alleen e.date bewaard en p.name in GROUP BY identieke sorteervolgorde in alle clausules hebben, in de hoop op een prestatievoordeel. Anders kunt u de kolommen daar verwijderen. (Vergelijkbaar voor slechts e.date in de eerste zoekopdracht.)