私は数時間、添字の基になる配列の基準に基づいて配列の添字をフィルター処理し、それらの添字の配列を作成する関数を作成しようと試みましたが、無駄でした。
私が扱っているデータ構造は、次のサンプルに似ています (比較する列が多く、ルールが複雑で、データ型が混在していることを除いて)。
id hierarchy abbreviation1 abbreviation2
1 {1} SB GL
2 {2,1} NULL NULL
3 {3,2,1} NULL TC
4 {4,2,1} NULL NULL
略語の単一の値を取得するために、abbreviation1 と abbreviation2 の親に最も近い次の非 null 値を取得し、現在のレコードからの階層距離に基づいてそれらを比較するクエリを実行する必要があります。したがって、たとえば、abbreviation1 と abbreviation2 の最初の非 null 値が両方とも同じレコード レベルにある場合、abbreviation1 が優先されます。一方、最初の null 以外の abbreviation2 が現在のレコードに近い場合は、abbreviation1 の対応する null 以外の値よりも近い場合、abbreviation2 が使用されます。
したがって、上記のサンプル テーブルで説明したクエリは次のようになります。
id abbreviation
1 SB
2 SB
3 TC
4 SB
このタスクを達成するarray_agg()
には、略語列の値が null ではない添字のみを含むフィルター処理された配列添字の配列を生成する必要があります (略語列で を実行した後)。
次の関数は、私の疲れた頭の中のすべてのロジックに基づいて動作するはずですが、動作しません
CREATE OR REPLACE FUNCTION filter_array_subscripts(rawarray anyarray,criteria anynonarray,dimension integer, reverse boolean DEFAULT False)
RETURNS integer[] as
$$
DECLARE
outarray integer[] := ARRAY[]::integer[];
x integer;
BEGIN
for i in array_lower(rawarray,dimension)..array_upper(rawarray,dimension) LOOP
IF NOT criteria IS NULL THEN
IF NOT rawarray[i] IS NULL THEN
IF NOT rawarray[i] = criteria THEN
IF reverse = False THEN
outarray := array_append(outarray,i);
ELSE
outarray := array_prepend(i,outarray);
END IF;
ELSE
IF reverse = False THEN
outarray := array_append(outarray,i);
ELSE
outarray := array_prepend(i,outarray);
END IF;
END IF;
END IF;
ELSE
IF NOT rawarray[i] is NULL THEN
IF reverse = False THEN
outarray := array_append(outarray,i);
ELSE
outarray := array_prepend(i,outarray);
END IF;
END IF;
END IF;
END LOOP;
RETURN outarray;
END;
$$ LANGUAGE plpgsql;
たとえば、次のクエリは、返す{5,3,1}
べきときに返されます{5,4,2,1}
select filter_array_subscripts(array['This',NULL,'is',NULL,'insane!']::text[]
,'is',1,True);
これが機能しない理由がforeach
わかりません。配列反復構文を使用してみましたが、反復値を に含まれるスカラー型にキャストする方法がわかりませんanyarray
。
これを修正するにはどうすればよいですか?