För att få resultatet utan underfråga , måste du tillgripa avancerade knep för fönsterfunktioner:
SELECT sum(count(*)) OVER () AS tickets_count
, sum(min(a.revenue)) OVER () AS atendees_revenue
FROM tickets t
JOIN attendees a ON a.id = t.attendee_id
GROUP BY t.attendee_id
LIMIT 1;
sqlfiddle
Hur fungerar det?
Nyckeln till att förstå detta är händelsernas sekvens i frågan:
aggregerade funktioner -> fönsterfunktioner -> DISTINKT -> GRÄNS
Mer information:
- Bästa sättet att få resultaträkningen innan LIMIT tillämpades
Steg för steg:
-
Jag
GROUP BY t.attendee_id
- vilket du normalt skulle göra i en underfråga. -
Sedan summerar jag räkningarna för att få det totala antalet biljetter. Inte särskilt effektivt, men tvingat av ditt krav. Den aggregerade funktionen
count(*)
är insvept i fönsterfunktionensum( ... ) OVER ()
för att komma fram till det inte så vanliga uttrycket:sum(count(*)) OVER ()
.Och summera minimiintäkterna per deltagare för att få summan utan dubbletter.
Du kan också använda
max()
elleravg()
istället förmin()
till samma effekt somrevenue
är garanterat densamma för varje rad per deltagare.Detta kan vara enklare om
DISTINCT
var tillåtet i fönsterfunktioner, men PostgreSQL har (ännu) inte implementerat denna funktion. Per dokumentation:Aggregerade fönsterfunktioner tillåter, till skillnad från vanliga aggregerade funktioner, inte
DISTINCT
ellerORDER BY
som ska användas i listan över funktionsargument. -
Sista steget är att få en enda rad. Detta kan göras med
DISTINCT
(SQL-standard) eftersom alla rader är samma.LIMIT 1
kommer dock att gå snabbare. Eller SQL-standardformenFETCH FIRST 1 ROWS ONLY
.