Vollständige Frage neu schreiben
Ich suche nach einer First () - Aggregatfunktion.
Hier habe ich etwas gefunden, das fast funktioniert:
CREATE OR REPLACE FUNCTION public.first_agg ( anyelement, anyelement )
RETURNS anyelement LANGUAGE sql IMMUTABLE STRICT AS $$
SELECT $1;
$$;
-- And then wrap an aggregate around it
CREATE AGGREGATE public.first (
sfunc = public.first_agg,
basetype = anyelement,
stype = anyelement
);
Das Problem ist, dass eine varchar (n) -Spalte, die die first () -Funktion durchläuft, in eine einfache varchar (ohne Größe) konvertiert wird. Beim Versuch, die Abfrage in einer Funktion als RETURNS SETOF anyelement zurückzugeben, wird die folgende Fehlermeldung angezeigt:
FEHLER: Die Struktur der Abfrage stimmt nicht mit dem Ergebnistyp der Funktion überein. SQL-Status: 42804 Detalhe: Die zurückgegebene Zeichenvariation stimmt nicht mit der erwarteten Zeichenvariation (40) in Spalte 2 überein. Kontext: PL / pgSQL-Funktion vsr_table_at_time (beliebiges Element, Zeitstempel ohne Zeitzone ) Zeile 31 bei RETURN QUERY
Auf derselben Wiki-Seite befindet sich ein Link zu einer C-Version der Funktion , die die oben genannten ersetzen würde. Ich weiß nicht, wie ich es installieren soll, aber ich frage mich, ob diese Version mein Problem lösen könnte.
Gibt es eine Möglichkeit, die obige Funktion so zu ändern, dass genau derselbe Typ der Eingabespalte zurückgegeben wird?
quelle
DISTINCT ON
funktioniert dies in diesem Fall nicht. Es ist keine Aggregatfunktion, Sie filtern die Daten tatsächlich und können sie nur einmal ausführen.Ja, ich habe einen einfachen Weg mit Ihrem Fall gefunden, indem ich einige Funktionen in PostgreSQL 9.4+ verwendet habe
Sehen wir uns dieses Beispiel an:
Ich hoffe, es wird Ihnen in Ihrem Fall helfen.
quelle
DOMAIN
Datentypen oder anderen kleinen Ausnahmen funktioniert . Es ist auch viel komplexer und zeitaufwendiger, ein Array des gesamten Datensatzes aufzubauen. Die einfache Lösung wäre, ein benutzerdefiniertes Aggregat zu erstellen, aber bisher habe ich selbst damit nicht die ideale Lösung gefunden. Fensterfunktionen sind auch schlecht, da sie nicht so verwendet werden können, wie Sie Aggregate verwenden könnten (mit FILTER-Anweisungen oder in CROSS JOIN LATERAL)Keine direkte Antwort auf Ihre Frage, aber Sie sollten die
first_value
Fensterfunktion ausprobieren . Das funktioniert so:);
Wenn Sie dann das erste Element in jeder
cat
(Kategorie) möchten, fragen Sie folgendermaßen ab:oder:
quelle
select distinct x, first_value(y) over (partition by x), first_value(z) over (partition by x) from ...
. Wahrscheinlich ineffizient, aber genug, um mit dem Prototyping fortzufahren. Auf jeden Fall etwas zu überdenken!