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.)