配列フィルタ・ステップ式

構文

array_filter_step ::= "[" [expression] "]"

セマンティクス

配列フィルタはマップ・フィルタに似ていますが、主に配列に使用するためのものです。配列フィルタ・ステップは、各要素の述語式を計算し、述語の結果に応じて要素を選択または拒否することによって、配列の要素を選択します。フィルタ・ステップの結果は、選択したすべての項目を含む順序になります。述語式がない場合は、定数trueであるとみなされます(この場合、すべての配列要素が返されます)。

配列フィルタ・ステップでは、各コンテキスト項目は次のように処理されます。
  • コンテキスト項目が配列でない場合は、配列が作成され、その配列にコンテキスト項目が追加されます。次に説明するように、この単一項目配列に配列フィルタが適用されます。
  • コンテキスト項目が配列の場合、ステップは配列要素を反復処理し、各要素の述語式を計算します。コンテキスト宣言変数($)の他に、述語式は次の2つの暗黙的に宣言された変数を参照できます。$elementはコンテキスト要素、つまり$の現在の要素にバインドされ、$posは配列内のコンテキスト要素の位置にバインドされます(位置は0からカウントされます)。述語式は、ブール項目、数値項目、空の順序またはNULLを返す必要があります。述語式のNULLまたは空の結果は、false値として扱われます。述語の結果がtrue/falseの場合、コンテキスト要素はそれぞれ選択/スキップされます。述語の結果が数値Pの場合、コンテキスト要素は条件$pos = Pがtrueの場合にのみ選択されます。これは、Pが負または配列サイズ以上の場合、コンテキスト要素はスキップされることを意味します。

例6-24 配列フィルタ・ステップ式

ユーザーごとに、姓と市外局番650の電話番号を選択します。

SELECT lastName,
[ u.address.phones[$element.area = 650].number ] 
AS phoneNumbers
FROM users u;

select句のパス式は、大カッコで囲まれています。これは、配列およびマップ・コンストラクタの項で説明されているように、配列コンストラクタ式に使用される構文です。明示的配列コンストラクタを使用すると、結果セット内のレコードが常に2番目のフィールドとして配列を持つことが保証されます。それ以外の場合、結果レコードには、複数の電話を持つユーザーの配列が含まれますが、1つの電話のみを持つユーザーの場合は単一の整数が含まれます。また、1つの電話のみを持つユーザーの場合、住所の電話フィールドは(単一の電話オブジェクトを含む)配列ではなく、単一の電話オブジェクトのみとなる場合があります。そのような単一の電話オブジェクトの市外局番が650の場合、想定どおりにその番号が選択されます。

例6-25 配列フィルタ・ステップ式

各ユーザーについて、姓と、そのユーザーの最初の電話番号と同じ市外局番を持つ電話番号を選択します。
SELECT lastName,
[ u.address.phones[$element.area = $[0].area].number ]
FROM users u;

例6-26 配列フィルタ・ステップ式

各ユーザーの最も強力な10の接続のうち、id > 100の接続を選択します。(接続配列は、接続の強さでソートされ、より強い接続が先に表示されると想定されます)。
SELECT [ connections[$element > 100 AND $pos < 10] ] 
AS interestingConnections 
FROM users;

例6-27 配列フィルタ・ステップ式

市外局番が650の電話番号の合計数をカウントします。
SELECT count(u.address.phones[$element.area = 650])
FROM users u;

例6-28 配列フィルタ・ステップ式

650の市外局番で少なくとも1つの電話を持つ人の総数をカウントするには、CASE式(CASE式を参照)とExists演算子(Exists演算子を参照)を使用する必要があります。
SELECT count(CASE
WHEN EXISTS u.address.phones[$element.area = 650] THEN 1
ELSE 0
END)
FROM users u;