これは機能します:
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;
電話:
SELECT * FROM avg_purchases('{foo,Bar,baz,"}weird_name''$$"}');
または(更新-ドル引用の例):
SELECT * FROM avg_purchases($x${foo,Bar,baz,"}weird_name'$$"}$x$);
-
文字列リテラルを引用する方法の詳細:
PostgreSQLで一重引用符を使用してテキストを挿入する -
ここでは動的SQLは必要ありません。
-
できる それをplpgsql関数(便利かもしれません)にラップすると、単純なSQL関数がうまく機能します。
-
タイプの不一致があります 。
-
avg()
の結果numeric
の場合があります 正確な結果を保持します。float8
にキャストしました それを機能させるために、これはdouble precision
の単なるエイリアスです (どちらでも使用できます)。完全な精度が必要な場合は、numeric
を使用してください 代わりに。 -
GROUP BY last_name
なので プレーンなtext
が必要ですtext[]
の代わりにOUTパラメータ 。
-
VARIADIC
配列は便利なタイプの入力です。クライアントにとってより簡単な場合は、 VARIADIC
を使用することもできます 配列を要素のリストとして渡すことを可能にする入力パラメータ :
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;
電話:
SELECT * FROM avg_purchases('foo', 'Bar', 'baz', '"}weird_name''$$"}');
または(ドル見積もりあり):
SELECT * FROM avg_purchases('foo', 'Bar', 'baz', $y$'"}weird_name'$$"}$y$);
標準のPostgresでは最大100要素しか許可されていないことに注意してください 。これは、コンパイル時にプリセットオプションによって決定されます:
max_function_args (integer)
関数の引数の最大数を報告します。
FUNC_MAX_ARGS
の値によって決定されます サーバーを構築するとき。デフォルト値は100引数です。
キーワードVARIADIC
を前に付けると、配列表記で呼び出すことができます。 :
SELECT * FROM avg_purchases(VARIADIC '{1,2,3, ... 99,100,101}');
より大きな配列(100以上)の場合は、unnest()
も使用します サブクエリとJOIN
それに、より適切にスケーリングする傾向があります:
- 大きなINを使用してPostgresクエリを最適化する