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

配列の配列をパラメーターとして関数に渡す

    私はあなたの2番目のアプローチが好きです。

    SELECT DISTINCT t.*
    FROM   (VALUES (1, 4), (5, 1), (2, 3), (1, 4), (7, 3), (7, 4)) AS t(a, b)
    JOIN   (
       SELECT arr[1]::int[] AS a1
             ,arr[2]::int[] AS b1
       FROM   (
          SELECT unnest(ARRAY['{"{1,2}", "{3,4}"}'
                             ,'{"{}"   , "{4,5,6}"}'
                             ,'{"{5}"  , "{}"}'    -- added element to 1st dimension
                             ])::text[] AS arr     -- 1d text array
          ) sub
       ) s ON (a = ANY(a1) OR a1 = '{}')
          AND (b = ANY(b1) OR b1 = '{}')
    ;
    

    マイナーな改善のみを提案する:

    1. パフォーマンスをわずかに向上させるために、CTEの代わりにサブクエリを実行します。

    2. 空の配列の簡略化されたテスト:リテラル'{}'に対するチェック 関数呼び出しの代わりに。

    3. 配列をアンラップするためのサブクエリレベルが1つ少なくなります。

    結果:

    a | b
    --+---
    2 | 3
    7 | 4
    1 | 4
    5 | 1
    

    カジュアルな読者の場合:Postgresは(エラーメッセージを引用して)次のことを要求するため、整数の多次元配列をラップする必要があります:

    代替ルート 2次元のテキスト配列を使用します generate_subscripts()を使用してそれをアンネストします :

    WITH a(arr) AS (SELECT '{{"{1,2}", "{3,4}"}
                            ,{"{}", "{4,5,6}"}
                            ,{"{5}", "{}"}}'::text[]   -- 2d text array
                 )
    SELECT DISTINCT t.*
    FROM  (VALUES (1, 4), (5, 1), (2, 3), (1, 4), (7, 3), (7, 4)) AS t(a, b)
    JOIN  (
       SELECT arr[i][1]::int[] AS a1
             ,arr[i][2]::int[] AS b1
       FROM   a, generate_subscripts(a.arr, 1) i       -- using implicit LATERAL
       ) s ON (t.a = ANY(s.a1) OR s.a1 = '{}')
          AND (t.b = ANY(s.b1) OR s.b1 = '{}');
    

    もっと速いかもしれませんが、テストできますか?

    9.3より前のバージョンでは、明示的なCROSS JOINを使用していました。 横方向の交差結合の代わりに。




    1. テーブルを読み取り専用としてマークするにはどうすればよいですか?

    2. MariaDBで月末を取得する方法

    3. Castle ActiverecordエラーはPostgresqlに「関係が存在しません」ですか?

    4. MySQL(InnoDB)のパフォーマンスに大きなばらつきがあるのはなぜですか?