13

これが私が理想的に望むものです。行Aのテーブルがあるとします。

私はやってみたいです:

SELECT A, func(A) FROM table

そして、出力には4つの列があると言います。

これを行う方法はありますか?カスタムタイプや、次のような結果を得ることができるものを見てきました

あいうえお)

しかし、その 1 つの関数で複数の列を返すことができれば、それ以上の手間がかからないのは本当に素晴らしいことです。

このようなことができるものはありますか?

4

4 に答える 4

19

関数funcが次のように 3 つの値を持つ 1 行のみを返す場合:

CREATE OR REPLACE FUNCTION func
(
    input_val       integer,
    OUT output_val1 integer,
    OUT output_val2 integer,
    OUT output_val3 integer
)
AS $$
BEGIN
  output_val1 := input_val + 1;
  output_val2 := input_val + 2;
  output_val3 := input_val + 3;
END;
$$ LANGUAGE plpgsql;

次に実行すると、次のようになりSELECT a, func(a) FROM table1ます。

a       | func
integer | record
========|==========
1       | (2, 3, 4)
2       | (3, 4, 5)
3       | (4, 5, 6)

ただし、実行すると:

SELECT a, (f).output_val1, (f).output_val2, (f).output_val3
FROM (SELECT a, func(a) AS f FROM table1) AS x

あなたが得るでしょう:

a       | output_val1 | output_val2 | output_val3
integer | integer     | integer     | integer
========|=============|=============|=============
1       | 2           | 3           | 4
2       | 3           | 4           | 5
3       | 4           | 5           | 6

または、CTE (Common Table Expressions) を使用して、次を実行する場合:

WITH temp AS (SELECT a, func(a) AS f FROM table1)
SELECT a, (f).output_val1, (f).output_val2, (f).output_val3 FROM temp

あなたも得るでしょう:

a       | output_val1 | output_val2 | output_val3
integer | integer     | integer     | integer
========|=============|=============|=============
1       | 2           | 3           | 4
2       | 3           | 4           | 5
3       | 4           | 5           | 6

注: 次のクエリを使用して同じ結果を取得することもできます。

SELECT a, (f).*
FROM (SELECT a, func(a) AS f FROM table1) AS x

また

WITH temp AS (SELECT a, func(a) AS f FROM table1)
SELECT a, (f).* FROM temp
于 2011-05-07T17:09:35.140 に答える
7

私は bambam の答えに同意しますが、JackPDouglas のより簡潔な構文SELECT a, (func(a)).* FROM table1は、私のテストから、返された列ごとに実際に関数を 1 回実行するのに対し、CTE 式は関数を 1 回だけ実行することを指摘したいと思います。そのため、関数の実行に時間がかかる場合は、CTE 式が優先されます。

于 2011-06-02T20:24:02.193 に答える
2

関数が常に 3 列を返す場合、次のようなことができます。

CREATE TYPE sometype AS (b INT, c TEXT, d TEXT);

CREATE OR REPLACE FUNCTION func(a TEXT) RETURNS SETOF sometype AS $$
BEGIN
  RETURN QUERY EXECUTE 'SELECT b, c, d FROM ' || a;
END;
$$ LANGUAGE plpgsql;

SELECT a, (f).b, (f).c, (f).d 
FROM (SELECT a, func(a) AS f FROM table) x;

ビュー内からテーブルにアクセスできる場合は、何らかの方法でビューを作成できる可能性があります

CREATE VIEW v AS 
SELECT 'tab1' AS a, b, c, d FROM tab1 WHERE 'tab1' IN (SELECT a FROM table)
UNION
SELECT 'tab2' AS a, b, c, d FROM tab2 WHERE 'tab2' IN (SELECT a FROM table)
UNION
SELECT 'tab3' AS a, b, c, d FROM tab3 WHERE 'tab3' IN (SELECT a FROM table);

それはただのSELECT * FROM v. しかし、これも継承を使用できるように見えます。

于 2011-03-29T12:20:30.127 に答える
0

複数の列を持つ単一のレコードを返したいと思いますか? その場合RECORD、たとえば return-type を使用できます。これにより、必要な数の列を持つ匿名変数を返すことができます。さまざまな変数の詳細については、次を参照してください。

http://www.postgresql.org/docs/9.0/static/plpgsql-declarations.html

戻り値の型について:

http://www.postgresql.org/docs/9.0/static/xfunc-sql.html#XFUNC-OUTPUT-PARAMETERS

複数の列を持つ複数のレコードを返したい場合は、まずこれにストアド プロシージャを使用する必要があるかどうかを確認してください。VIEW代わりに a (および WHERE 句を使用してクエリを実行) を使用することも選択肢の 1 つかもしれません。TABLEそれが適切でない場合は、バージョン 9.0 のストアド プロシージャから aを返す可能性があります。

于 2011-03-28T22:11:13.493 に答える