配列の操作
スライス・ステップまたはフィルタ・ステップを使用して、配列から要素を選択できます。まず、スライス・ステップを使用した例から始めます。
各個人の2つ目の関連付けを選択して表示するには、次の問合せを使用します。
sql-> SELECT lastname, connections[1]
AS connection FROM Persons;
+----------+------------+
| lastname | connection |
+----------+------------+
| Scully | 2 |
| Smith | 4 |
| Morgan | 2 |
| Anderson | 2 |
| Morrison | 2 |
+----------+------------+
5 rows returned
この例では、スライス・ステップ[1]
がconnections配列に適用されます。配列要素は0から始まるため、1を指定すると2つ目のconnection値が選択されます。
スライス・ステップを使用して、その位置が[low:high]の範囲内にあるすべての配列要素を選択することもできます。ここで、lowとhighは範囲の限度を指定する式です。下限と上限が不要な場合は、lowとhighの式は省略できます。
たとえば、次の問合せでは、個人5の姓と最初の3つの関連付けがstrongconnectionsとして戻されます。
sql-> SELECT lastname, [connections[0:2]]
AS strongconnections FROM Persons WHERE id = 5;
+----------+-------------------+
| lastname | strongconnections |
+----------+-------------------+
| Scully | 2 |
| | 4 |
| | 1 |
+----------+-------------------+
1 row returned
個人5に対する前述の問合せでは、パス式connections[0:2]
によって、その個人の最初の3つの関連付けが戻されます。ここで、範囲は[0:2]であるため、0がlow式で、2がhighです。パス式は、3つの項目のリストとして結果を戻します。配列コンストラクタ式([])でパス式を囲むと、リストが配列(単一項目)に変換されます。配列コンストラクタは、3つの関連付けを含む新しい配列を作成します。問合せシェルには作成されたこの配列の要素が縦に表示されますが、この問合せによって戻される行の数は1であることに注意してください。
select句での配列コンストラクタの使用はオプションです。配列コンストラクタを使用しない場合でも、配列は作成されますが、select句式で実際に複数の項目が戻された場合にのみ作成されます。戻された項目が1つのみの場合は、結果にはその1つの項目のみが含まれます。式から何も戻されない(空の結果が戻される)場合は、NULLが結果として使用されます。この動作を、配列コンストラクタを使用して実行する場合の例と、使用しないで実行する場合の例を使用して説明します。
前述したように、スライス・ステップの範囲を指定する場合は、low式またはhigh式は省略できます。たとえば、次の問合せでは、3つ目の関連付けより後のすべての関連付けを戻す[3:]の範囲を指定します。配列コンストラクタを使用しているため、関連付けが3つ以下である個人の場合は、空の配列が作成されて戻されることに注意してください。
COLUMNモードでは単一の項目と単一の項目を含む配列が区別されないため、この動作を完全に説明するために、mode JSON
でこの出力を表示します。
sql-> mode JSON
Query output mode is JSON
sql-> SELECT id, [connections[3:]] AS weakConnections FROM Persons;
{"id":3,"weakConnections":[]}
{"id":4,"weakConnections":[2]}
{"id":2,"weakConnections":[]}
{"id":5,"weakConnections":[3]}
{"id":1,"weakConnections":[]}
5 rows returned
次に、配列コンストラクタを使用せずに同じ問合せを実行します。単一の項目は配列に格納されず、一致のない行では、空の配列のかわりにNULLが戻されることに注意してください。
sql-> SELECT id, connections[3:] AS weakConnections FROM Persons;
{"id":2,"weakConnections":null}
{"id":3,"weakConnections":null}
{"id":4,"weakConnections":2}
{"id":5,"weakConnections":3}
{"id":1,"weakConnections":null}
5 rows returned
sql-> mode COLUMN
Query output mode is COLUMN
sql->
スライス・ステップの最後の例として、次の問合せでは、各個人の最後の3つの関連付けを戻します。この問合せでは、スライス・ステップは[size($)-3:]
です。この式で、$はスライス・ステップが適用される配列を参照する、暗黙的に宣言された変数です。この例では、$はconnections配列を参照します。size()組込み関数は、入力配列のサイズ(要素の数)を戻します。つまり、この例では、size($)は現在のconnections配列のサイズです。最後に、size($)-3は、現在のconnections配列の最後から3番目の位置を計算します。
sql-> SELECT id, [connections[size($)-3:]]
AS weakConnections FROM Persons;
+----+-------------------+
| id | weakConnections |
+----+-------------------+
| 5 | 4 |
| | 1 |
| | 3 |
+----+-------------------+
| 4 | 5 |
| | 1 |
| | 2 |
+----+-------------------+
| 3 | 1 |
| | 4 |
| | 2 |
+----+-------------------+
| 2 | 1 |
| | 3 |
+----+-------------------+
| 1 | 2 |
| | 3 |
+----+-------------------+
5 rows returned
次に、配列のフィルタ・ステップに移ります。スライス・ステップと同様に、フィルタ・ステップでも角カッコ([])構文を使用します。ただし、[]内に含まれる内容は異なります。フィルタ・ステップでは、[]内には何も入らないか、条件として機能する(ブール値の結果を戻す)単一の式が入ります。前者の場合は、配列のすべての要素が選択されます(配列はネストされていません)。後者の場合、条件は各要素に順番に適用され、結果がtrueの場合は要素が選択され、そうでない場合はスキップされます。次に例を示します。
次の問合せは、個人4に関連付けられている個人のIDと関連付けを戻します。
sql-> SELECT id, connections
FROM Persons p WHERE p.connections[] =any 4;
+----+-------------+
| id | connections |
+----+-------------+
| 3 | 1 |
| | 4 |
| | 2 |
+----+-------------+
| 5 | 2 |
| | 4 |
| | 1 |
| | 3 |
+----+-------------+
2 rows returned
前述の問合せでは、式p.connections[]
によって個人のすべての関連付けが戻されます。次に、この関連付けのシーケンスに数値4が含まれる場合、=any演算子はtrueを戻します。
次の問合せは、IDが4より大きい個人に関連付けられている個人のIDと関連付けを戻します。
sql-> SELECT id, connections FROM Persons p
WHERE p.connections[] >any 4;
+----+-------------+
| id | connections |
+----+-------------+
| 4 | 3 |
| | 5 |
| | 1 |
| | 2 |
+----+-------------+
1 row returned
次の問合せは、個人ごとに、その個人の姓と市外局番が339である電話番号を戻します。
sql-> SELECT lastname,
[ p.address.phones[$element.areacode = 339].number ]
AS phoneNumbers FROM Persons p;
+----------+--------------+
| lastname | phoneNumbers |
+----------+--------------+
| Scully | 3414578 |
+----------+--------------+
| Smith | 4120211 |
| | 8694021 |
| | 1205678 |
+----------+--------------+
| Morgan | |
+----------+--------------+
| Anderson | 1684972 |
+----------+--------------+
| Morrison | |
+----------+--------------+
5 rows returned
前述の問合せでは、フィルタ・ステップ[$element.areacode = 339]
が各個人のphones配列に適用されています。フィルタ・ステップによって、配列の各要素について条件$element.areacode = 339
が評価されます。この条件式では、配列の現在の要素を参照する、暗黙的に宣言された変数の$elementを使用しています。市外局番が339の電話番号を持たない個人には、空の配列が戻されます。このような個人を結果から除外する必要がある場合は、次の問合せを作成します。
sql-> SELECT lastname,
[ p.address.phones[$element.areacode = 339].number ]
AS phoneNumbers FROM Persons p WHERE p.address.phones.areacode =any 339;
+----------+--------------+
| lastname | phoneNumbers |
+----------+--------------+
| Scully | 3414578 |
+----------+--------------+
| Smith | 4120211 |
| | 8694021 |
| | 1205678 |
+----------+--------------+
| Anderson | 1684972 |
+----------+--------------+
3 rows returned
前述の問合せには、パス式p.address.phones.areacode
が含まれています。この式では、フィールド・ステップ.areacode
が配列フィールド(phones)に適用されます。この場合、フィールド・ステップは配列の各要素に順番に適用されます。実際には、このパス式はp.address.phones[].areacode
と同等です。
暗黙的に宣言された$変数と$element変数に加えて、フィルタ・ステップ内の条件では、$pos変数(これも暗黙的に宣言されています)も使用できます。$posは、現在の要素(条件が適用される要素)の配列内の位置を参照します。たとえば、次の問合せでは各個人の"関心の高い"関連付けが選択され、関連付けの関心が高いと見なされるのは、それが最も強い3つの関連付けに含まれ、かつ、IDが4以上の個人に関連付けられている場合です。
sql-> SELECT id, [p.connections[$element >= 4 and $pos < 3]]
AS interestingConnections FROM Persons p;
+----+------------------------+
| id | interestingConnections |
+----+------------------------+
| 5 | 4 |
+----+------------------------+
| 4 | 5 |
+----+------------------------+
| 3 | 4 |
+----+------------------------+
| 2 | |
+----+------------------------+
| 1 | |
+----+------------------------+
5 rows returned
最後に、通常の比較演算子(=、!=、>、>=、>および>=)を使用して、2つの配列を互いに比較できます。たとえば、次の問合せでは配列[1,3]を作成し、そのconnections配列が[1,3]に等しい個人を選択します。
sql-> SELECT lastname FROM Persons p
WHERE p.connections = [1,3];
+----------+
| lastname |
+----------+
| Anderson |
+----------+
1 row returned