Chcete-li získat výsledek bez dílčího dotazu , musíte se uchýlit k triku s pokročilými funkcemi oken:
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
Jak to funguje?
Klíčem k pochopení je sekvence událostí v dotazu:
agregační funkce -> funkce okna -> DISTINCT -> LIMIT
Další podrobnosti:
- Nejlepší způsob, jak získat počet výsledků před použitím LIMIT
Krok za krokem:
-
I
GROUP BY t.attendee_id
- což byste normálně provedli v dílčím dotazu. -
Poté sečtem počty, abych získal celkový počet vstupenek. Ne příliš efektivní, ale vynucené vaším požadavkem. Agregační funkce
count(*)
je zabaleno do funkce oknasum( ... ) OVER ()
abychom dospěli k nepříliš běžnému výrazu:sum(count(*)) OVER ()
.A sečtěte minimální tržby na účastníka, abyste získali součet bez duplicit.
Můžete také použít
max()
neboavg()
místomin()
se stejným účinkem jakorevenue
je zaručeno, že bude stejný pro každý řádek na účastníka.To by mohlo být jednodušší, pokud
DISTINCT
byl povolen ve funkcích okna, ale PostgreSQL tuto funkci (zatím) neimplementoval. Podle dokumentace:Agregační funkce okna, na rozdíl od normálních agregačních funkcí, neumožňují
DISTINCT
neboORDER BY
k použití v seznamu argumentů funkcí. -
Posledním krokem je získání jednoho řádku. To lze provést pomocí
DISTINCT
(standard SQL), protože všechny řádky jsou stejné.LIMIT 1
bude však rychlejší. Nebo standardní formulář SQLFETCH FIRST 1 ROWS ONLY
.