Das funktioniert:
CREATE OR REPLACE FUNCTION avg_purchases(last_names text[] = '{}')
RETURNS TABLE(last_name text, avg_purchase_size float8) AS
$func$
SELECT last_name, AVG(purchase_size)::float8
FROM purchases
WHERE last_name = ANY($1)
GROUP BY last_name
$func$ LANGUAGE sql;
Aufruf:
SELECT * FROM avg_purchases('{foo,Bar,baz,"}weird_name''$$"}');
Oder (aktualisieren - Beispiel mit Dollar-Quote):
SELECT * FROM avg_purchases($x${foo,Bar,baz,"}weird_name'$$"}$x$);
-
Weitere Informationen zum Zitieren von Zeichenfolgenliteralen:
Text mit einfachen Anführungszeichen in PostgreSQL einfügen -
Sie brauchen hier kein dynamisches SQL.
-
Solange Sie können packen Sie es in eine plpgsql-Funktion (was nützlich sein kann), eine einfache SQL-Funktion erledigt die Arbeit gut.
-
Sie haben nicht übereinstimmende Typen .
- das Ergebnis von
avg()
kannnumeric
sein um ein genaues Ergebnis zu halten. Ich caste zufloat8
damit es funktioniert, was nur ein Alias fürdouble precision
ist (Sie können beides verwenden). Wenn Sie absolute Genauigkeit benötigen, verwenden Sienumeric
stattdessen. - Da Sie
GROUP BY last_name
Sie möchten einen einfachentext
OUT-Parameter anstelle vontext[]
.
- das Ergebnis von
VARIADIC
Ein Array ist ein nützlicher Eingabetyp. Wenn es für Ihren Kunden einfacher ist, können Sie auch einen VARIADIC
verwenden Eingabeparameter, der es erlaubt, das Array als Liste von Elementen zu übergeben :
CREATE OR REPLACE FUNCTION avg_purchases(VARIADIC last_names text[] = '{}')
RETURNS TABLE(last_name text, avg_purchase_size float8) AS
$func$
SELECT last_name, AVG(purchase_size)::float8
FROM purchases
JOIN (SELECT unnest($1)) t(last_name) USING (last_name)
GROUP BY last_name
$func$ LANGUAGE sql;
Aufruf:
SELECT * FROM avg_purchases('foo', 'Bar', 'baz', '"}weird_name''$$"}');
Oder (mit Anführungszeichen in Dollar):
SELECT * FROM avg_purchases('foo', 'Bar', 'baz', $y$'"}weird_name'$$"}$y$);
Beachten Sie, dass Standard-Postgres nur maximal 100 Elemente zulässt . Dies wird zur Kompilierzeit durch die voreingestellte Option bestimmt:
max_function_args (integer)
Meldet die maximale Anzahl von Funktionsargumenten. Er wird durch den Wert von FUNC_MAX_ARGS
bestimmt beim Aufbau des Servers. Der Standardwert ist 100 Argumente.
Sie können es immer noch in Array-Notation aufrufen, wenn das Schlüsselwort VARIADIC
vorangestellt ist :
SELECT * FROM avg_purchases(VARIADIC '{1,2,3, ... 99,100,101}');
Für größere Arrays (100+) würde ich auch unnest()
verwenden in einer Unterabfrage und JOIN
dazu, was tendenziell besser skaliert:
- Optimieren einer Postgres-Abfrage mit einem großen IN