

# SELECT コマンド
<a name="s3-select-sql-reference-select"></a>

**重要**  
新規のお客様への Amazon S3 Select の提供は終了しました。Amazon S3 Select をご利用の既存のお客様は、今後も通常どおり使用できます。[詳細情報](https://aws.amazon.com/blogs/storage/how-to-optimize-querying-your-data-in-amazon-s3/) 

Amazon S3 セレクトは、`SELECT` SQL コマンドのみをサポートします。次の ANSI スタンダードの句は、`SELECT` 用にサポートされています。


+ `SELECT` リスト
+ `FROM` 句 
+ `WHERE` 句
+ `LIMIT` 句

**注記**  
Amazon S3 Select クエリは、現在サブクエリや結合はサポートしていません。

## SELECT のリスト
<a name="s3-select-sql-reference-select-list"></a>

`SELECT` リストは、クエリに返させる列、関数、および式を指定します。このリストは、クエリの出力を表しています。

```
SELECT *
SELECT projection1 AS column_alias_1, projection2 AS column_alias_2
```

`*` (アスタリスク) を使用した最初の `SELECT` 形式では、`WHERE` 句を通過したすべての行がそのまま返されます。2 番目の `SELECT` 形式では、列ごとにユーザー定義の出力スカラー式 **`projection1`** および **`projection2`** を含む行が作成されます。

## FROM 句
<a name="s3-select-sql-reference-from"></a>

Amazon S3 Select では、`FROM` 句の以下の形式がサポートされています。

```
FROM table_name
FROM table_name alias
FROM table_name AS alias
```

`FROM` 句の各形式で、`table_name` はクエリの対象となる `S3Object` です。従来のリレーショナルデータベースから移行したユーザーは、これをテーブルに対する複数のビューを含むデータベーススキーマとして考えることができます。

スタンダード SQL に従って、`FROM` 句は `WHERE` 句でフィルタリングされ `SELECT` リストで射影される行を作成します。

Amazon S3 Select に格納されている JSON オブジェクトでは、次の形式の `FROM` 句も使用することができます。

```
FROM S3Object[*].path
FROM S3Object[*].path alias
FROM S3Object[*].path AS alias
```

この形式の `FROM` 句を使用すると、JSON オブジェクト内の配列またはオブジェクトから選択できます。以下のいずれかの形式で `path` を指定できます。
+ 名前 (オブジェクト内): `.name` または `['name']`
+ インデックス (配列内): `[index]`
+ ワイルドカード文字 (オブジェクト内): `.*`
+ ワイルドカード文字 (配列内): `[*]`

**注記**  
この形式の `FROM` 句は JSON オブジェクトに対してのみ機能します。
ワイルドカード文字は常に最低 1 つのレコードを発行します。レコードが一致しない場合、Amazon S3 Select は値 `MISSING` を発行します。出力のシリアル化中 (クエリの実行の完了後)、Amazon S3 Select は `MISSING` 値を空のレコードに置き換えます。
集約関数 (`AVG`、`COUNT`、`MAX`、`MIN`、および `SUM`) は、`MISSING` 値をスキップします。
エイリアスを指定せずにワイルドカード文字を使用する場合は、パスの最後の要素を使用して行を参照できます。例えば、クエリ `SELECT price FROM S3Object[*].books[*].price` を使用して、ブックのリストからすべての価格を選択できます。パスが名前ではなくワイルドカード文字で終わる場合は、値 `_1` を使用して行を参照できます。例えば、`SELECT price FROM S3Object[*].books[*].price` の代わりにクエリ `SELECT _1.price FROM S3Object[*].books[*]` を使用できます。
Amazon S3 Select は常に JSON ドキュメントをルートレベルの値の配列として扱います。したがって、クエリ対象の JSON オブジェクトにルート要素が 1 つしかない場合でも、`FROM` 句は `S3Object[*]` で始める必要があります。ただし、互換性の理由から、パスを含めない場合、Amazon S3 Select ではワイルドカード文字を省略できます。そのため、完全な句 `FROM S3Object` は、`FROM S3Object[*] as S3Object` と同等です。パスを含める場合は、ワイルドカード文字も使用する必要があります。つまり、`FROM S3Object` と `FROM S3Object[*].path` はどちらも有効な句ですが、`FROM S3Object.path` は有効な句ではありません。

**Example**  
**例:**  
*例 1:*  
この例では、以下のデータセットとクエリを使用した場合の結果を示しています。  

```
{ "Rules": [ {"id": "1"}, {"expr": "y > x"}, {"id": "2", "expr": "z = DEBUG"} ]}
{ "created": "June 27", "modified": "July 6" }
```

```
SELECT id FROM S3Object[*].Rules[*].id
```

```
{"id":"1"}
{}
{"id":"2"}
{}
```
Amazon S3 Select は、以下の理由で次の結果を生成します。  
+ `{"id":"id-1"}` — `S3Object[0].Rules[0].id` は一致を生成しました.
+ `{}` — `S3Object[0].Rules[1].id` はレコードと一致しなかったため、Amazon S3 Select が `MISSING` を出力しました。これは、出力のシリアル化中に空のレコードに変更されて返されます。
+ `{"id":"id-2"}` — `S3Object[0].Rules[2].id` は一致を生成しました。
+ `{}` — `S3Object[1]` は `Rules` で一致しなかったため、Amazon S3 Select が `MISSING` を出力しました。これは、出力のシリアル化中に空のレコードに変更されて返されます。
一致が見つからないときに Amazon S3 Select が空のレコードを返さないようにするには、`MISSING` という値をテストします。次のクエリは前のクエリと同じ結果を返しますが、空の値は省略されています。  

```
SELECT id FROM S3Object[*].Rules[*].id WHERE id IS NOT MISSING
```

```
{"id":"1"}
{"id":"2"}
```
*例 2:*  
この例は、以下のデータセットとクエリを使用した場合の結果を示しています。  

```
{ "created": "936864000", "dir_name": "important_docs", "files": [ { "name": "." }, { "name": ".." }, { "name": ".aws" }, { "name": "downloads" } ], "owner": "Amazon S3" }
{ "created": "936864000", "dir_name": "other_docs", "files": [ { "name": "." }, { "name": ".." }, { "name": "my stuff" }, { "name": "backup" } ], "owner": "User" }
```

```
SELECT d.dir_name, d.files FROM S3Object[*] d
```

```
{"dir_name":"important_docs","files":[{"name":"."},{"name":".."},{"name":".aws"},{"name":"downloads"}]}
{"dir_name":"other_docs","files":[{"name":"."},{"name":".."},{"name":"my stuff"},{"name":"backup"}]}
```

```
SELECT _1.dir_name, _1.owner FROM S3Object[*]
```

```
{"dir_name":"important_docs","owner":"Amazon S3"}
{"dir_name":"other_docs","owner":"User"}
```

## WHERE 句
<a name="s3-select-sql-reference-where"></a>

`WHERE` 句は、この構文に従います。

```
WHERE condition
```

`WHERE` 句は `condition` に基づいて行をフィルタリングします。condition は、ブール型の結果を持つ式です。condition の結果が `TRUE` である行のみが結果で返されます。

## LIMIT 句
<a name="s3-select-sql-reference-limit"></a>

`LIMIT` 句は、この構文に従います。

```
LIMIT number
```

`LIMIT` 句により、`number` に基づいてクエリで返されるレコードの数を制限できます。

## 属性アクセス
<a name="s3-select-sql-reference-attribute-access"></a>

`SELECT` 句および `WHERE` 句は、クエリ対象のファイルが CSV 形式であるか JSON 形式にあるかによって、以下のセクションのいずれかのメソッドを使用してレコードデータを参照できます。

### CSV
<a name="s3-select-sql-reference-attribute-access-csv"></a>
+ **列番号** – 行の *N 番目*の列を参照できます。`_N` は列名、*`N`* は列位置です。位置カウントは 1 から始まります。たとえば、最初の列名は `_1` で、2 番目の列名は `_2` です。

  列は `_N` または `alias._N` として参照できます。たとえば、`_2` と `myAlias._2` はどちらも `SELECT` リストおよび `WHERE` 句の列を参照するのに有効な方法です。
+ **列ヘッダー** – ヘッダー行を持つ CSV 形式のオブジェクトの場合、ヘッダーは `SELECT` リストおよび `WHERE` 句で利用できます。特に、従来の SQL では、`SELECT` および `WHERE` 句の式内で、`alias.column_name` または `column_name` で列を参照できます。

### JSON
<a name="s3-select-sql-reference-attribute-access-json"></a>
+ **ドキュメント** – JSON ドキュメントのフィールドは `alias.name` としてアクセスできます。ネストされたフィールド (`alias.name1.name2.name3` など) にもアクセスできます。
+ **リスト** – `[]` 演算子でゼロベースのインデックスを使用して、JSON リストの要素にアクセスできます。例えば、リストの 2 番目の要素に `alias[1]` としてアクセスできます。アクセスするリスト要素とフィールドを組み合わせることができます (例: `alias.name1.name2[1].name3`)。
+ **例:** この JSON オブジェクトをサンプルデータセットとして考えます。

  ```
  {"name": "Susan Smith",
  "org": "engineering",
  "projects":
      [
       {"project_name":"project1", "completed":false},
       {"project_name":"project2", "completed":true}
      ]
  }
  ```

  *例 1:*

  以下のクエリは次の結果を返します。

  ```
  Select s.name from S3Object s
  ```

  ```
  {"name":"Susan Smith"}
  ```

  *例 2*

  以下のクエリは次の結果を返します。

  ```
  Select s.projects[0].project_name from S3Object s
  ```

  ```
  {"project_name":"project1"}
  ```

## ヘッダーおよび属性名の大文字と小文字の区別
<a name="s3-select-sql-reference-case-sensitivity"></a>

Amazon S3 Select では、二重引用符を使用して、列ヘッダー (CSV オブジェクトの場合) および属性 (JSON オブジェクトの場合) の大文字と小文字を区別することを指定できます。二重引用符がない場合、オブジェクトヘッダーおよび属性の大文字と小文字は区別されません。あいまいな場合はエラーがスローされます。

以下の例は、1) 指定された列ヘッダーを持ち、クエリリクエストに対して `FileHeaderInfo` が `"Use"` に設定されている CSV 形式 の Amazon S3 オブジェクト、または 2) 指定された属性を持つ JSON 形式の Amazon S3 オブジェクトのいずれかです。

*例 \$11:* クエリ対象のオブジェクトには `NAME` というヘッダーまたは属性があります。
+ 次の式は、オブジェクトから値を正常に返します。引用符がないため、クエリの大文字と小文字は区別されません。

  ```
  SELECT s.name from S3Object s
  ```
+ 次の式は 400 エラー `MissingHeaderName` を返します。引用符があるため、クエリの大文字と小文字は区別されます。

  ```
  SELECT s."name" from S3Object s
  ```

*例 \$12:* クエリ対象の Amazon S3 オブジェクトには `NAME` という 1 つのヘッダーまたは属性と、`name` という別のヘッダーまたは属性があります。
+ 次の式は 400 エラー `AmbiguousFieldName` を返します。引用符がないため、クエリの大文字と小文字は区別されませんが、2 つの一致があるため、エラーがスローされます。

  ```
  SELECT s.name from S3Object s
  ```
+ 次の式は、オブジェクトから値を正常に返します。引用符があるため、クエリの大文字と小文字が区別されるため、あいまいさはありません。

  ```
  SELECT s."NAME" from S3Object s
  ```

## ユーザー定義の用語としての予約キーワードの使用
<a name="s3-select-sql-reference-using-keywords"></a>

Amazon S3 Select には、オブジェクトのコンテンツのクエリに使用する SQL 式を実行するために必要な予約キーワードのセットがあります。予約キーワードには、関数名、データ型、演算子などが含まれます。場合によっては、列ヘッダー (CSV ファイルの場合) や属性 (JSON オブジェクトの場合) などのユーザー定義の用語が、予約キーワードと競合する可能性があります。その場合は、二重引用符を使用して、予約キーワードと競合するユーザー定義の用語を意図的に使用していることを示す必要があります。そうしないと、400 解析エラーが発生します。

予約キーワードの詳細なリストについては、「[予約済みキーワード](s3-select-sql-reference-keyword-list.md)」を参照してください。

次の例は、1) Amazon S3 オブジェクトが CSV 形式で、指定された列ヘッダーを持ち、クエリリクエストに対して `FileHeaderInfo` が `"Use"` に設定されているか、2) Amazon S3 オブジェクトが JSON 形式で、指定された属性を持っています。

*例:* クエリ対象のオブジェクトに、予約キーワードである `CAST` という名前のヘッダーまたは属性があります。
+ 次の式は、オブジェクトから値を正常に返します。クエリで引用符が使用されているため、S3 Select はユーザー定義のヘッダーまたは属性を使用します。

  ```
  SELECT s."CAST" from S3Object s
  ```
+ 次の式は 400 解析エラーを返します。クエリで引用符が使用されていないため、`CAST` は予約キーワードと競合します。

  ```
  SELECT s.CAST from S3Object s
  ```

## スカラー式
<a name="s3-select-sql-reference-scalar"></a>

`WHERE` 句および `SELECT` リスト内では、スカラー値を返す式である SQL *スカラー式*を持つことができます。それには以下の形式があります。
+ ***`literal`*** 

  SQL リテラル。
+ ***`column_reference`*** 

  形式が `column_name` または `alias.column_name` である列への参照。
+ **`unary_op`** **`expression`** 

  この場合、****`unary_op`**** は SQL 単項演算子です。
+ **`expression`** **`binary_op`** ***`expression`*** 

   この場合、****`binary_op`**** は SQL 二項演算子です。
+ **`func_name`** 

   この場合、**`func_name`** は、呼び出すスカラー関数の名前です。
+ ***`expression`*** `[ NOT ] BETWEEN` ****`expression`**** `AND` ****`expression`****
+ ***`expression`*** `LIKE` ****`expression`**** [ `ESCAPE` ***`expression`*** ]