Ini berfungsi:
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;
Telepon:
SELECT * FROM avg_purchases('{foo,Bar,baz,"}weird_name''$$"}');
Atau (perbarui - contoh dengan kutipan dolar):
SELECT * FROM avg_purchases($x${foo,Bar,baz,"}weird_name'$$"}$x$);
-
Selengkapnya tentang cara mengutip literal string:
Menyisipkan teks dengan tanda kutip tunggal di PostgreSQL -
Anda tidak memerlukan SQL dinamis di sini.
-
Sementara Anda bisa bungkus menjadi fungsi plpgsql (yang mungkin berguna), fungsi SQL sederhana bekerja dengan baik.
-
Anda memiliki ketidakcocokan jenis .
- hasil dari
avg()
mungkinnumeric
untuk menahan hasil yang tepat. Saya melakukan transmisi kefloat8
untuk membuatnya berfungsi, yang hanya merupakan alias untukdouble precision
(Anda dapat menggunakan keduanya). Jika Anda membutuhkan presisi yang sempurna, gunakannumeric
sebagai gantinya. - Karena Anda
GROUP BY last_name
Anda ingintext
biasa Parameter OUT bukannyatext[]
.
- hasil dari
VARIADIC
Array adalah jenis input yang berguna. Jika lebih mudah untuk klien Anda, Anda juga dapat menggunakan VARIADIC
parameter input yang memungkinkan untuk melewatkan array sebagai daftar elemen :
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;
Telepon:
SELECT * FROM avg_purchases('foo', 'Bar', 'baz', '"}weird_name''$$"}');
Atau (dengan kutipan dolar):
SELECT * FROM avg_purchases('foo', 'Bar', 'baz', $y$'"}weird_name'$$"}$y$);
Ketahuilah bahwa Postgres standar hanya mengizinkan maksimum 100 elemen . Ini ditentukan pada waktu kompilasi oleh opsi yang telah ditetapkan:
max_function_args (integer)
Melaporkan jumlah maksimum argumen fungsi. Itu ditentukan oleh nilai
FUNC_MAX_ARGS
saat membangun server. Nilai default adalah 100 argumen.
Anda masih dapat memanggilnya dengan notasi array ketika diawali dengan kata kunci VARIADIC
:
SELECT * FROM avg_purchases(VARIADIC '{1,2,3, ... 99,100,101}');
Untuk array yang lebih besar (100+), saya juga akan menggunakan unnest()
dalam subquery dan JOIN
untuk itu, yang cenderung berskala lebih baik:
- Mengoptimalkan kueri Postgres dengan IN besar