2016-12-29 20 views
1

pl/pgsqlでカスタム関数を作成しましたが、入力は配列のみです。私はこのカスタム関数の入力としてクエリの結果を使用したいと思いますが、それを正しく得ることはできません。私は例として単純な関数を使用し、入力として使用しようとしているものより単純なクエリを使用します。カスタム関数の配列パラメータ(入力)としてSQLクエリを使用します。

関数定義:

CREATE OR REPLACE FUNCTION bigger_than_ones(input_array int[]) 
returns SETOF int 
AS 
$$ 
DECLARE 
    array_item int; 
BEGIN 
    FOREACH array_item in ARRAY input_array 
    LOOP 
    IF array_item > 1 THEN 
     RETURN NEXT array_item; 
    END IF; 
    END LOOP; 
END 
$$ LANGUAGE plpgsql; 

私は、列配列のデータ型の同じデータ型を持つテーブルを持っています。この場合、整数列:

SELECT * FROM my_table; 
id | int_attribute 
---+-------------- 
1 | 2 
2 | 3 
3 | 1 
4 | 4 
5 | 1 
6 | 6 
7 | 1 
8 | 1 
9 | 8 

このデータ型の列を関数の入力として返すクエリを使用したいと思います。私は運がなくて、これのいくつかのバリエーションを試してみた:

SELECT * FROM bigger_than_ones(SELECT int_attribute FROM my_table); 

を返すには:

result 
------------- 
2 
3 
4 
6 
8 

私がマージされた時間を結果として計算する必要があるので、私は同様の構成機能を使用している理由は、範囲(カスタムタイプ)を複数のテーブルから、私のコードの複数の場所に配置します。私の最善の考えは、どこから取得したかに関係なく、すべての時間範囲を入力として使用する関数を作成することでしたので、毎回より複雑なクエリを作成する必要はありませんでした。

私が紛失していると思うことはありますか?

+1

クエリで達成しようとしていることがわかりません。あなたの質問を編集して、そのデータに基づいてサンプルデータと予想される出力を加えてください。 [_Formatted_](http://stackoverflow.com/help/formatting)** text **お願い、[スクリーンショットなし](http://meta.stackoverflow.com/questions/285551/why-may-i-not -upload-images-of-if-ask-a-question/285557#285557) –

+0

は単純に 'int_attribute>を' my_tableからint_attributeを選択しますか? –

+0

あなたの関数は**配列**を期待しています。単純な整数値を渡すことができる(またはすべきである)のはなぜだと思いますか?なぜあなたはそのようなあなたの機能を定義しましたか? –

答えて

1

ARRAY constructorは、ではなく、であり、演算子(または関数)ではなくSQL構文(SQL構文要素)です。参照された回答で間違った用語が使用されました(現在は修正済みです)。違いは重要かもしれません。

SELECT * FROM bigger_than_ones(ARRAY(SELECT int_attribute FROM my_table)); 

また、より複雑なクエリを中に統合することが容易である、基本的なaggregate function array_agg()を使用することができます - しかし、単純なケースのために遅い:

SELECT * FROM bigger_than_ones((SELECT array_agg(int_attribute) FROM my_table)); 

関連:

私はあなたがunnest()

CREATE OR REPLACE FUNCTION bigger_than_ones(input_array int[]) 
    RETURNS SETOF int AS 
$func$ 
    SELECT * 
    FROM unnest(input_array) elem 
    WHERE elem > 1; 
$func$ LANGUAGE sql; 

また、多くの場合、このすべてに優れたセットベースのアプローチがあります:根本的にテスト機能を簡素化するために使用することができます。セットから配列を作成するだけで、それを関数に渡すことは不要な複雑さかもしれません。

+0

'unnest()'について知らなかったので、とても役に立ちました。私が同様に構造化された関数を使用している理由は、複数のテーブルから、結果として得られるマージされた時間範囲(カスタムタイプ)をコード内の複数の場所で計算する必要があるためです。私の最善の考えは、どこから取得したかに関係なく、すべての時間範囲を入力として使用する関数を作成することでしたので、毎回より複雑なクエリを作成する必要はありませんでした。申し訳ありませんが、何かが十分に明確でない場合、英語は私の母国語ではありません。 – shevia

+0

@shevia:更新後、問題は十分明確です。実際よりもはっきりしています。 1つの大きな欠点:あなたのPostgresのバージョンは*すべての*質問で宣言されるべきです。ちょうどそこに言及したかったほうが良い方法かもしれません。そうでないかもしれない。たぶんカスタム集計関数ですか?または、 'tstzrange(min(lower(...)、max(upper(...))'。あなたの設定と要件の*正確な*詳細を別の質問にしたいかもしれません。 –

-2

カスタムタイプを作成しようとしましたか?配列や表などのコレクション型があり、単一行レコードに似たオブジェクト型があります。このカスタムタイプの変数を作成して、パラメータとして使用できます。ここ

は、例えば次のとおり

はVARCHAR2(10)のVARRAY(3)のようなタイプのnamearrayを作成するか、またはREPLACE。

+1

Postgresには無効です –

0

私は最終的に、別のSO問題の解決策が見つかりました:Store select query's output in one array in postgres

は、私は次のように配列()演算子を使用することができました:

SELECT * FROM bigger_than_ones(ARRAY(SELECT int_attribute FROM my_table)); 

を、期待される出力を得ました。

関連する問題