sql >> データベース >  >> RDS >> PostgreSQL

デフォルトの順序に基づいて2セットを結合します

    さて、本物に答える コメントで明らかにされた質問。これは次のように見えます:

    これに取り組むにはいくつかの方法があります:

    • 配列の長さが等しい場合にのみ、複数のunnestを使用します SELECTの関数 句(下位互換性のためにのみ使用する必要がある非推奨のアプローチ);

    • generate_subscriptsを使用します 配列をループする;

    • generate_seriesを使用します array_lowerに対するサブクエリ およびarray_upper generate_subscriptsをエミュレートします generate_subscriptsを使用するには古すぎるバージョンをサポートする必要がある場合;

    • unnestの順序に依存する 私の他の回答のように、そして以下に示すように、タプルを返し、期待しています。動作しますが、将来のバージョンで動作することは保証されていません。

    • WITH ORDINALITYを使用します PostgreSQL9.4で追加された機能最初の投稿 も参照してください。 )unnestの行番号を取得します 9.4が出たとき。

    • 複数配列のUNNESTを使用する 、これはSQL標準ですが、どのPostgreSQLですまだサポートしていません

    したがって、関数arraypairがあるとします。 配列パラメータa およびb

    CREATE OR REPLACE FUNCTION arraypair (a integer[], b text[]) 
    RETURNS TABLE (col_a integer, col_b text) AS $$
      -- blah code here blah
    $$ LANGUAGE whatever IMMUTABLE;
    

    そしてそれは次のように呼び出されます:

    SELECT * FROM arraypair( ARRAY[1,2,3,4,5,6,7], ARRAY['a','b','c','d','e','f','g'] );
    

    可能な関数定義は次のとおりです。

    SRF-in- SELECT (非推奨)

    CREATE OR REPLACE FUNCTION arraypair (a integer[], b text[])
    RETURNS TABLE (col_a integer, col_b text) AS $$
        SELECT unnest(a), unnest(b);
    $$ LANGUAGE sql IMMUTABLE;
    

    配列の長さが等しくない場合、奇妙で予期しない結果が生成されます。 SELECTの集合戻り関数とその非標準使用に関するドキュメントを参照してください。 理由と正確に何が起こるかを学ぶためのリスト。

    generate_subscripts

    これはおそらく最も安全なオプションです:

    CREATE OR REPLACE FUNCTION arraypair (a integer[], b text[])
    RETURNS TABLE (col_a integer, col_b text) AS $$
        SELECT
           a[i], b[i]
        FROM generate_subscripts(CASE WHEN array_length(a,1) >= array_length(b,1) THEN a::text[] ELSE b::text[] END, 1) i;
    $$ LANGUAGE sql IMMUTABLE;
    

    配列の長さが等しくない場合、記述されているように、短い方の配列はnull要素を返すため、完全な外部結合のように機能します。ケースの感覚を逆にして、内部結合のような効果を得る。この関数は、配列が1次元であり、インデックス1から始まることを前提としています。配列引数全体がNULLの場合、関数はNULLを返します。

    より一般化されたバージョンはPL/PgSQLで記述され、array_ndims(a) = 1をチェックします。 、array_lower(a, 1) = 1を確認してください 、null配列のテストなど。それはあなたにお任せします。

    ペアワイズリターンの希望:

    これは動作が保証されていませんが、PostgreSQLの現在のクエリエグゼキュータで動作します:

    CREATE OR REPLACE FUNCTION arraypair (a integer[], b text[])
    RETURNS TABLE (col_a integer, col_b text) AS $$
     WITH
        rn_c1(rn, col) AS (
          SELECT row_number() OVER (), c1.col
          FROM unnest(a) c1(col) 
        ),
        rn_c2(rn, col) AS (
          SELECT row_number() OVER (), c2.col
          FROM unnest(b) c2(col)
        )
        SELECT
          rn_c1.col AS c1, 
          rn_c2.col AS c2
        FROM rn_c1 
        INNER JOIN rn_c2 ON (rn_c1.rn = rn_c2.rn);
    $$ LANGUAGE sql IMMUTABLE;
    

    generate_subscriptsの使用を検討します はるかに安全です。

    マルチ引数unnest

    これはすべき 動作しますが、PostgreSQLのunnestが原因で動作しません (まだ)複数の入力配列を受け入れません:

    SELECT * FROM unnest(a,b);
    


    1. 非ラテン文字と痛い

    2. executeQuery()を使用してデータ操作ステートメントを発行することはできません

    3. mysqlの2つのタイムスタンプ間の時間差を計算します

    4. スタンバイの追加中にエラーが発生しました