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()mungkinnumericuntuk menahan hasil yang tepat. Saya melakukan transmisi kefloat8untuk membuatnya berfungsi, yang hanya merupakan alias untukdouble precision(Anda dapat menggunakan keduanya). Jika Anda membutuhkan presisi yang sempurna, gunakannumericsebagai gantinya. - Karena Anda
GROUP BY last_nameAnda ingintextbiasa 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_ARGSsaat 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