7.16.1. between#
7.16.1.1. 概要#
between は、指定された値が指定された範囲にあるかをチェックするために使われます。これは select の filter オプションと組み合わせてよく使われます。
7.16.1.2. 構文#
between は3つから6つの引数を受け取ります。
between(column_or_value, min, max)
between(column_or_value, min, max, {"option": "value of option"})
between(column_or_value, min, min_border, max, max_border)
between(column_or_value, min, min_border, max, max_border, {"option": "value of option"})
7.16.1.3. 使い方#
使い方を示すために使うスキーマ定義とサンプルデータは以下の通りです。
実行例:
table_create Users TABLE_HASH_KEY ShortText
# [[0,1337566253.89858,0.000355720520019531],true]
column_create Users age COLUMN_SCALAR Int32
# [[0,1337566253.89858,0.000355720520019531],true]
table_create Ages TABLE_HASH_KEY Int32
# [[0,1337566253.89858,0.000355720520019531],true]
column_create Ages user_age COLUMN_INDEX Users age
# [[0,1337566253.89858,0.000355720520019531],true]
load --table Users
[
{"_key": "Alice", "age": 12},
{"_key": "Bob", "age": 13},
{"_key": "Calros", "age": 15},
{"_key": "Dave", "age": 16},
{"_key": "Eric", "age": 20},
{"_key": "Frank", "age": 21}
]
# [[0,1337566253.89858,0.000355720520019531],6]
これはPG-13 (MPAA)のレーティングに該当する人を示すクエリです。
実行例:
select Users --filter 'between(age, 13, "include", 16, "include")'
# [
# [
# 0,
# 1337566253.89858,
# 0.000355720520019531
# ],
# [
# [
# [
# 3
# ],
# [
# [
# "_id",
# "UInt32"
# ],
# [
# "_key",
# "ShortText"
# ],
# [
# "age",
# "Int32"
# ]
# ],
# [
# 2,
# "Bob",
# 13
# ],
# [
# 3,
# "Calros",
# 15
# ],
# [
# 4,
# "Dave",
# 16
# ]
# ]
# ]
# ]
13から16歳までのユーザーを返します。
between 関数はテーブルのカラムだけでなく、値も受け付けます。
最初の引数に値を指定した場合、その値が含まれているか否かをチェックします。もし、指定した範囲にマッチしたら、( between 関数がtrueを返すので)すべてのレコードを返します。もし、指定した範囲にマッチしなかった場合、( between 関数がfalseを返すので)1件もレコードを返しません。
実行例:
select Users --filter 'between(14, 13, "include", 16, "include")'
# [
# [
# 0,
# 1337566253.89858,
# 0.000355720520019531
# ],
# [
# [
# [
# 6
# ],
# [
# [
# "_id",
# "UInt32"
# ],
# [
# "_key",
# "ShortText"
# ],
# [
# "age",
# "Int32"
# ]
# ],
# [
# 1,
# "Alice",
# 12
# ],
# [
# 2,
# "Bob",
# 13
# ],
# [
# 3,
# "Calros",
# 15
# ],
# [
# 4,
# "Dave",
# 16
# ],
# [
# 5,
# "Eric",
# 20
# ],
# [
# 6,
# "Frank",
# 21
# ]
# ]
# ]
# ]
上記の例では、すべてのレコードを返します。これは、14は指定した範囲である13から16の間にあるからです。この振舞いは指定した値がテーブルに存在するかどうかの確認に使えます。
Added in version 16.0.6: between は最初の引数としてベクターも受け付けます。
ベクターはシーケンシャルサーチでのみサポートしています。 between はまだベクターの値に対してインデックスを使いません。
最初の引数には、 COLUMN_VECTOR カラムやベクターリテラルなどのベクターの値を指定できます。この場合、 between はいずれかの要素が指定した範囲に含まれていればtrueを返します。そのため、 between を使って、範囲内に少なくとも1つの値を持つレコードを検索できます。
以下の例では COLUMN_VECTOR カラムを使います。各レコードは複数の価格を持ちます。 between は、 [18, 20) の範囲に少なくとも1つの価格が含まれるレコードを選択します。
実行例:
table_create Products TABLE_HASH_KEY ShortText
# [[0,1337566253.89858,0.000355720520019531],true]
column_create Products prices COLUMN_VECTOR Int32
# [[0,1337566253.89858,0.000355720520019531],true]
load --table Products
[
{"_key": "A", "prices": [17, 170, 1700]},
{"_key": "B", "prices": [18, 180, 1800]},
{"_key": "C", "prices": [19, 190]},
{"_key": "D", "prices": [20]},
{"_key": "E", "prices": [21, 210, 2100]}
]
# [[0,1337566253.89858,0.000355720520019531],5]
select Products --filter 'between(prices, 18, "include", 20, "exclude")'
# [
# [
# 0,
# 1337566253.89858,
# 0.000355720520019531
# ],
# [
# [
# [
# 2
# ],
# [
# [
# "_id",
# "UInt32"
# ],
# [
# "_key",
# "ShortText"
# ],
# [
# "prices",
# "Int32"
# ]
# ],
# [
# 2,
# "B",
# [
# 18,
# 180,
# 1800
# ]
# ],
# [
# 3,
# "C",
# [
# 19,
# 190
# ]
# ]
# ]
# ]
# ]
A と E は、どの価格も範囲内にないため除外されます。 D は、 20 が "exclude" によって除外されるため除外されます。 B と C は、それぞれ範囲内に少なくとも1つの価格を持つため選択されます。
ベクターの要素が異なる型を使っている場合、最初の要素の型が対象の型として使われ、他の型を使っている要素は無視されます。例えば、 [180.0, 18] では、最初の要素 180.0 が浮動小数点数で 18 はそうではないため、 18 は無視されます。
また、 between はオプションも指定できます。現在は、 too_many_index_match_ratio のみ指定できます。この値は、 double 型です。
too_many_index_match_ratio を使って、 GRN_BETWEEN_TOO_MANY_INDEX_MATCH_RATIO の値を変更できます。GRN_BETWEEN_TOO_MANY_INDEX_MATCH_RATIO のデフォルト値は 0.01 です。GRN_BETWEEN_TOO_MANY_INDEX_MATCH_RATIO は、 between がインデックスを使うかどうかを決定するために使います。
between とANDで絞り込むと予想されるレコード数よりも、絞り込んだレコード数が十分に小さい場合は、インデックスを使った検索より、シーケンシャルサーチの方が速いことがあります。
例えば、 --filter でレコードを絞り込んだあと、さらに between で絞り込むとします。
デフォルトでは、以下のケースでは、 between はシーケンシャルサーチを使います。
--filterで絞り込んだレコード数が1000でbetween対象のレコード数が500,000の場合。1,000/500,000 = 0.002 < 0.01(GRN_BETWEEN_TOO_MANY_INDEX_MATCH_RATIO) -> between use sequential search.
一方、以下のケースでは、 between はインデックスを使います。
--filterで絞り込んだレコード数が1000でbetween対象のレコード数が50,000の場合。1,000/50,000 = 0.02 > 0.01(GRN_BETWEEN_TOO_MANY_INDEX_MATCH_RATIO) -> between use index.
between のオプションを設定するクエリーは以下の通りです。:
実行例:
select Users --filter 'between(age, 13, "include", 16, "include", {"too_many_index_match_ratio":0.001})'
# [
# [
# 0,
# 1337566253.89858,
# 0.000355720520019531
# ],
# [
# [
# [
# 3
# ],
# [
# [
# "_id",
# "UInt32"
# ],
# [
# "_key",
# "ShortText"
# ],
# [
# "age",
# "Int32"
# ]
# ],
# [
# 2,
# "Bob",
# 13
# ],
# [
# 3,
# "Calros",
# 15
# ],
# [
# 4,
# "Dave",
# 16
# ]
# ]
# ]
# ]
7.16.1.4. 引数#
7.16.1.4.1. 必須引数#
必須引数は3つあります。 column_or_value と min と max です。
7.16.1.4.1.1. column_or_value#
カラムもしくは値を指定します。
Added in version 16.0.6: ベクターもシーケンシャルサーチでのみ受け付けます。 between はいずれかの要素が指定した範囲に含まれていればtrueを返します。詳細は 使い方 を参照してください。
7.16.1.4.1.2. min#
範囲のうち最小値を指定します。デフォルトでは min を範囲に含めますが、 min_border 引数で含めるかどうかを制御できます。
7.16.1.4.1.3. max#
範囲のうち最大値を指定します。デフォルトでは値 max を範囲に含めますが、 max_border 引数で含めるかどうかを制御できます。
7.16.1.4.2. 省略可能引数#
省略可能引数は2つあります。 min_border と max_border です。
7.16.1.4.2.1. min_border#
min の値を含めた範囲となるかどうかを指定します。 min_border に指定できるのは "include" または "exclude" のどちらかです。
"include" を指定すれば、min が含まれます。 "exclude" を指定すれば min は含まれません。
7.16.1.4.2.2. max_border#
man の値を含めた範囲となるかどうかを指定します。 max_border に指定できるのは "include" または "exclude" のどちらかです。
"include" を指定すれば、max が含まれます。 "exclude" を指定すれば max は含まれません。
7.16.1.4.2.3. {"option": "value of option"}#
between のオプションを指定します。現在は、 too_many_index_match_ratio のみ指定できます。この値は、 double 型です。
7.16.1.4.2.4. 戻り値#
between は指定した範囲にカラムの値が含まれるかを返します。もし該当するレコードがあれば、 true を返します。そうでなければ false を返します。