私の関数はint4
を引数として、テーブルを返します。
SELECT * FROM test_function(545421); -- works fine
SELECT * FROM test_function(SELECT customerid
FROM tableX where id = 1); -- syntax error
どうすればこれを機能させることができますか?
サーバーPostgreSQL 9.3.1
@ a_horse のような括弧でそれを修正することができます:
SELECT * FROM test_function((SELECT customerid FROM tableX where id = 1));
しかし、このフォームはかなりエラーが発生しやすくなります。コードには、副選択が単一の行のみを返すことを保証するものはありません。 id
が一意であるかどうか、またPostgresも一意であるかどうかはわかりません(システムカタログを検索しない限り)。私たちはそれに依存する必要があり、壊れないことを願っています。
確かにLIMIT 1
を追加することもできますが、決定的な結果を得るためにORDER BY
も追加する必要があります...
JOIN LATERAL
この(Postgres9.3+)の最新の構文は、LATERAL
結合になります。
SELECT f.*
FROM tableX t, test_function(t.customerid) f
WHERE t.id = 1;
これは短い構文です:
SELECT f.*
FROM tableX t
CROSS JOIN LATERAL test_function(t.customerid) f
WHERE t.id = 1;
上記とまったく同じ結果ですが、1つ微妙ですが重要な違いがある可能性があります:
tableX
にt.id = 1
の行が行がない場合、関数は呼び出されず、クエリは何も返しません(行なし)。一方、customerid IS NULL
で行が見つかった場合、関数はNULL
入力で呼び出され、関数がNULL
に対して返すものをすべて取得します。customerid
がNULL
であることと同じNULL値になります。関数は、どちらの方法でもNULL
入力で呼び出されます。LATERAL
クエリは、id
が一意でない場合でもブレークしません。また、必要に応じて、tableX
から追加の列を簡単に返すことができます。