選択句の構文
適用対象: WatchGuard Advanced EPDR
このトピックでは、SQL SELECT ステートメントの一般的な構文について説明します。
SELECT [DISTINCT] expr_list
[FROM [db.] table | (subquery) | table_function]
[SAMPLE sample_coeff]
[GLOBAL] [ANY|ALL] [INNER|LEFT|RIGHT|FULL|CROSS] [OUTER] JOIN (subquery)|table USING columns_list
[PREWHERE expr]
[WHERE expr]
[GROUP BY expr_list] [WITH TOTALS]
[HAVING expr]
[ORDER BY expr_list]
[LIMIT [n, ]m]
[UNION ALL...]
[LIMIT n BY columns]
SQL クエリでは、以下の句を使用することができます。
- FROM 句
- SAMPLE 句
- JOIN 句
- WHERE 句
- PREWHERE 句
- GROUP BY 句
- LIMIT N BY Columns 句
- HAVING 句
- ORDER BY 句
- SELECT 句
- DISTINCT 句
- LIMIT m 句
- UNION ALL 句
- IN 演算子
- アスタリスク記号 (*)
FROM 句
FROM 句は、データの読み取り元となるソース (例:テーブル、サブクエリ、JOIN 句) を指定します。サブクエリは括弧で囲む必要があります。標準 SQL とは異なり、サブクエリの後にシノニムを指定する必要はありません。互換性のために、サブクエリの後に「name AS」を記述することはできますが、指定された名前は使用されません。
SAMPLE 句
SAMPLE 句は近似データのクエリを処理します。
SAMPLE 句を使用すると、クエリはすべてのデータに対して実行されるのではなく、データの一部 (サンプル) に対してのみ実行されます。たとえば、多数のイベントの統計を計算する必要がある場合は、すべてのイベントの 10% にクエリを実行して、その結果を 10 倍にするだけで十分です。
近似クエリ処理は、以下のような場合に有用となります。
- 迅速に結果を収集する必要がある場合。
- 生データが正確でない場合。この場合は、近似値を使用しても結果の品質が著しく低下することはありません。
データ サンプリングの特徴は、以下の通りです。
- これは、決定論的メカニズムです。同じクエリの結果が常に同じになります。
- 異なるテーブルで一貫して機能します。単一のサンプリング キーを持つテーブルの場合は、同じ係数のサンプルは常に同じデータのサブセットを選択します。つまり、IN 句のサブクエリでサンプルを使用できるということです。JOIN 句を使用して、サンプルを結合することもできます。
- ディスクから読み取るデータ量を減少させることができます。サンプリング キーを正しく指定する必要があります。
SAMPLE 句の構文:
| 構文 | 説明 |
|---|---|
|
SAMPLE k |
0 〜 1 の数字です。クエリは、データの k % の割合で実行されます。たとえば、SAMPLE 0.1 は、データの 10% にクエリが実行されます。 |
|
SAMPLE n |
n は、十分に大きな整数です。クエリは、少なくとも n 行 (しかし、行がこれを大幅に超えることはありません) のサンプルに実行されます。たとえば、SAMPLE 10000000 は、最低 10,000,000 行にクエリが実行されます。 |
|
SAMPLE k OFFSET m |
k と m は、0 〜 1 の数字です。クエリは、データの k % のサンプルに実行されます。サンプルに使用されるデータは m % でオフセットされます。 |
JOIN 句
JOIN は、リレーショナル代数の結合操作を示すものです。これにより、1 つまたは複数のテーブルの列が結合され、テーブルに格納される新規グループまたはそのまま使用できる新規グループが作成されます。新規テーブルを作成する場合は、JOIN は複数のテーブルの共通値を使用して列を結合します。
サポートされている JOIN 句の種類は、以下の通りです。
- INNER JOIN (または JOIN) — テーブル A の各行をテーブル B の行と比較し、ON 句で指定されている結合述語を満たすすべての行のペアを検索します。結合述語が NULL 以外の値と一致する場合は、テーブル A と B で一致した行の各ペアの列値が結果行に結合されます。
- LEFT JOIN (または LEFT OUTER JOIN) — 結合条件が「右側」のテーブル (テーブル B) の行と一致しない場合でも、常に「左側」のテーブル (テーブル A) のすべての行が含まれます。つまり、ON 句がテーブル B の 0 行 (テーブル A の特定の行) に一致する場合は、結合によって結果に行 (その行) が返されますが、テーブル B の各列には NULL が含まれるということです。
- RIGHT JOIN (または RIGHT OUTER JOIN) — 結合条件が「左側」のテーブル (テーブル A) の行と一致しない場合でも、常に「右側」のテーブル (テーブル B) のすべての行が含まれます。つまり、ON 句がテーブル A の 0 行 (テーブル B の特定の行) に一致する場合は、結合によって結果に行 (その行) が返されますが、テーブル A の各列には NULL が含まれるということです。
- FULL JOIN (または FULL OUTER JOIN) — LEFT JOIN と RIGHT JOIN の効果の組み合わせです。完全外部結合テーブルの行が一致しない場合は、一致する行のないテーブルのすべての列の結果セットに NULL 値が含まれます。一致する行については、両方のテーブルから入力された列が含まれている 1 つの行が結果セットに生成されます。
- CROSS JOIN (または , ) — 結合のテーブルの行のカルテシアン積を返します。最初のテーブルの各行と 2 番目のテーブルの各行を結合した行が生成されます。
- ANY または ALL 修飾子 — ALL が指定されており、右側のテーブルに一致する行が複数ある場合は、データは行数で乗算されます。これは標準 SQL の JOIN 句の通常動作です。ANY が指定されており、右側のテーブルに一致する行が複数ある場合は、最初に見つかった行のみが結合されます。右側のテーブルに一致する行が 1 つしかない場合は、ANY と ALL の結果は同じになります。
WHERE 句
WHERE 句がある場合は、UInt8 型の式を含める必要があります。これは通常、比較演算子と論理演算子が含まれている式です。この式は、ステートメントに含まれているすべての変換が実行される前にデータをフィルタリングするために使用されます。
PREWHERE 句
この句には WHERE 句と同じ意味があります。異なる点は、テーブルから読み取られるデータです。PREWHERE の場合は、句の実行に必要な列が最初に読み取られます。次に、PREWHERE 式が true の場合に、クエリの残りの部分を実行するために必要な列が読み取られます。
PREWHERE ではデータがより効率的にフィルタリングされ、クエリ実行時にディスクから読み取られるデータが少なくなります。
GROUP BY 句
この句は、結果を 1 つまたは複数の列ごとにグループ化します。グループ化の場合、Endpoint Security では NULL が値として解釈されます。
WITH TOTALS 修飾子が指定されている場合は、別の行が計算されます。この行には、既定値 (ゼロまたは空行) が含まれるキー列、およびすべての行にわたって計算された値 (合計値) が含まれる集計関数の列があります。この追加の行は、JSON、TabSeparated、Pretty 形式でのみ生成されます。JSON 形式では、この行は個別の合計フィールドとして出力されます。TabSeparated 形式では、行はメインの結果の後に配置され、その前に空の行が入ります。Pretty 形式では、行はメインの結果の後に別のテーブルとして出力されます。
サブクエリで WITH TOTALS を使用することができます。これには、JOIN 句内のサブクエリが含まれます (この場合、それぞれの合計値が結合されます)。
Caution: MySQL (および標準 SQL) とは異なり、GROUP BY ステートメントでは位置引数がサポートされていません。たとえば、GROUP BY 1, 2 は、定数によるグループ化 (つまり、すべての行を 1 つにまとめる) として解釈されます。
LIMIT N BY Columns 句
この句は、列の各グループの最初の N 行を選択します。LIMIT N BY は LIMIT と無関係です。どちらも同じクエリで使用することができます。LIMIT N BY には、任意の数の列または式を含めることができます。
HAVING 句
この句を使用することで、GROUP BY で生成された集計結果をフィルタリングすることができます。これは WHERE 句に似ていますが、WHERE は集計 (GROUP BY) の前に実行されるのに対し、HAVING は集計の後に実行されるという点が異なります。集計を実行しない場合は、HAVING を使用することはできません。
Caution: MySQL (および標準 SQL 準拠) とは異なり、GROUP BY ステートメントでは位置引数がサポートされていません。
ORDER BY 句
ORDER BY 句には、式のリストが含まれています。並べ替えの方向を決定するために、それぞれに DESC (降順) または ASC (昇順) 修飾子を付けることができます。方向が指定されていない場合は、ASC が前提となります。並べ替えの方向は、リスト全体ではなく、単一の式に適用されます。
並べ替えの式のリストと同じ値を持つ行は任意の順序で出力されますが、その順序は毎回異なる場合があります。ORDER BY 句を省略すると、行の順序が定義されなくなり、毎回異なる可能性があります。
COLLATE
文字列値で並べ替える場合は、COLLATE を使用して、使用するアルファベットを指定することができます。たとえば、ORDER BY SearchPhrase COLLATE 'tr' を使用すれば、トルコ語のアルファベットで、大文字と小文字を区別せずにキーワードの昇順で並べ替えることが可能です。これは、文字列が UTF-8 でエンコードされていることを前提としています。
各式に対して COLLATE を指定するかどうかを個別に指定することができます。ASC または DESC を指定する場合は、その後に COLLATE を指定します。COLLATE を使用する場合は、常に並べ替えで大文字と小文字が区別されません。
COLLATE を使用する並べ替えは通常のバイトによる並べ替えよりも効率が悪いため、少数の行の最終的な並べ替えにのみ COLLATE を使用することが勧められます。
NaN と NULL 並べ替え順序:
- NULLS FIRST 修飾子を使用する場合 — 最初に NULL、次に NaN、最後に他の値の順序
- NULLS LAST 修飾子を使用する場合 — 最初に値、次に NaN、最後に NULL の順序
- 既定 — NULLS LAST 修飾子の場合と同じ順序
浮動小数点数を並べ替える場合は、NaN は他の値から分離されます。並べ替え順序に関係なく、NaN は最後になります。昇順の並べ替えの場合は、これは他すべての数値よりも大きいかのように配置されます。降順の並べ替えの場合は、これは他の数値よりも小さいかのように配置されます。
SELECT 句
SELECT 句で指定される式は、前述の句のすべての操作が終了した後に計算されます。SELECT 句の式に集計関数が含まれている場合は、ソリューションで、GROUP BY 集計時に集計関数とその引数として使用される式が処理されます。こうした式は、結果の個別の行に適用されるかのように機能します。
DISTINCT 句
DISTINCT を指定すると、結果における完全一致の行のすべてのセットのうち 1 行だけが残ります。集計関数を使用せずに、SELECT 句として指定したのと同じ値のセットに GROUP BY を適用しても、同じ結果が出る可能性があります。DISTINCT 句と GROUP BY 句の相違点は、以下の通りです。
-
DISTINCT は GROUP BY と一緒に適用することができます。
-
ORDER BY を省略して LIMIT を定義すると、必要な数の異なる行が読み取られた後にクエリが直ちに停止します。
-
データ ブロックは、クエリ全体が完了するのを待たずに、処理と同時に出力されます。
DISTINCT では、NULL が特定の値であるかのように NULL が処理されます。つまり、DISTINCT 結果では、NULL の異なる組み合わせは 1 回のみ発生しているものということです。
LIMIT m 句
この句は、結果から最初の m 行を選択します。
LÍMIT n, m は、最初の n 行を省略した後、結果から最初の m 行を選択します。LIMIT m OFFSET n 構文は同等です。n と m は負でない整数でなければなりません。
結果を明示的に並べ替える ORDER BY 句がない場合は、結果の行の選択は任意かつ非決定的になる可能性があります。
UNION ALL 句
この句を使用して、任意の数のクエリを組み合わせることができます。UNION ALL のみがサポートされます。UNION (UNION DISTINCT) はサポートされません。UNION DISTINCT が必要な場合は、UNION ALL が含まれているサブクエリの SELECT DISTINCT を入力することができます。UNION ALL の一部であるクエリは同時に実行して、その結果を混在させることができます。
結果の構造 (列の数と型) はクエリと一致している必要がありますが、列名は異なっても構いません。この場合は、最終結果の列名は最初のクエリから取得されます。共同体 (union) に型キャスト (型変換) が実行されます。たとえば、互換性のある型から Null 非許容型と Null 許容型の同じフィールドを使用して 2 つのクエリを結合すると、結果の UNION ALL には Null 許容型のフィールドが含まれます。
UNION ALL の一部であるクエリを括弧で囲むことはできません。ORDER BY と LIMIT は、最終結果ではなく、個別のクエリに適用されます。最終結果に変換を適用する必要がある場合は、FROM 句のサブクエリに UNION ALL を含めたすべてのクエリを配置することができます。
IN 演算子
このセクションでは、IN、NOT IN、GLOBAL IN、GLOBAL NOT IN 演算子について説明します。
IN 演算子の左側は、単一の列かタプルのいずれかです。たとえば、SELECT UserID IN (123, 456) FROM .. となります。
左側がインデックス内の単一の列であり、右側が定数のセットである場合は、システムでインデックスを使用してクエリが処理されます。
演算子の右側は、定数式のセット、タプルのセット、データベース テーブルの名前、括弧で囲まれた SELECT サブクエリのいずれかとなります。サブクエリでは、タプルをフィルタリングするために複数の列を指定することができます。例:
SELECT (CounterID, UserID) IN (SELECT CounterID, UserID FROM ...) FROM ...
IN 演算子の左側と右側の列は、同じ型である必要があります。
IN 演算子とサブクエリは、集計関数やラムダ関数を含め、クエリのどの部分でも使用することができます。
NULL 処理
IN 演算子の場合、NULL が演算子の右側にあるか左側にあるかに関係なく、NULL を使用した演算の結果は常に 0 になることが前提です。NULL 値はどのデータセットにも含まれず、相互に対応していないだけでなく、比較もできません。
アスタリスク記号 (*)
式の代わりに、クエリのどの部分にもアスタリスクを含めることができます。クエリの分析時に、アスタリスクがすべてのテーブル列のリストに展開されます。
以下の場合に、アスタリスクを使用することができます。
- テーブル ダンプを作成する場合。
- 少数の列のみが含まれているテーブルの場合。少数の列で強力なフィルタリングを行う場合は、PREWHERE を使用します。
- テーブルの列に関する情報を取得する場合。この場合は、LIMIT 1 を設定します。DESC TABLE クエリを使用することが勧められます。
- サブクエリで、外部クエリに必要のない列をサブクエリから除外する場合。
それ以外の場合は、パフォーマンスの問題を防ぐために、アスタリスクを使用しないことが勧められます。