PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Rufen Sie die eindeutige Summe einer verknüpften Tabellenspalte ab

Um das Ergebnis ohne Unterabfrage zu erhalten , müssen Sie auf fortgeschrittene Fensterfunktionstricks zurückgreifen:

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

Wie funktioniert es?

Der Schlüssel zum Verständnis ist die Reihenfolge der Ereignisse in der Abfrage:

Aggregatfunktionen -> Fensterfunktionen -> DISTINCT -> LIMIT

Weitere Einzelheiten:

  • Bester Weg, um die Ergebnisanzahl zu erhalten, bevor LIMIT angewendet wurde

Schritt für Schritt:

  1. I GROUP BY t.attendee_id - was Sie normalerweise in einer Unterabfrage tun würden.

  2. Dann summiere ich die Zählungen, um die Gesamtzahl der Tickets zu erhalten. Nicht sehr effizient, aber durch Ihre Anforderung gezwungen. Die Aggregatfunktion count(*) wird in die Fensterfunktion sum( ... ) OVER () eingeschlossen um zu dem nicht ganz so gebräuchlichen Ausdruck zu kommen:sum(count(*)) OVER () .

    Und addieren Sie den Mindestumsatz pro Teilnehmer, um die Summe ohne Duplikate zu erhalten.

    Sie könnten auch max() verwenden oder avg() statt min() mit der gleichen Wirkung wie revenue ist garantiert für jede Zeile pro Teilnehmer gleich.

    Dies könnte einfacher sein, wenn DISTINCT war in Fensterfunktionen erlaubt, aber PostgreSQL hat diese Funktion (noch) nicht implementiert. Per Dokumentation:

    Aggregatfensterfunktionen erlauben im Gegensatz zu normalen Aggregatfunktionen DISTINCT nicht oder ORDER BY innerhalb der Funktionsargumentliste verwendet werden.

  3. Der letzte Schritt besteht darin, eine einzelne Zeile zu erhalten. Dies könnte mit DISTINCT erfolgen (SQL-Standard), da alle Zeilen gleich sind. LIMIT 1 wird aber schneller. Oder die SQL-Standardform FETCH FIRST 1 ROWS ONLY .