

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 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 僅支援 `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` 子句的每個資料列。`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 物件。
萬用字元一律至少會發出一個記錄。如果沒有相符的記錄，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 物件僅具有一個根元素，`FROM` 子句也必須以 `S3Object[*]` 開頭。但基於相容性因素，Amazon S3 Select 允許您在不包含路徑的情況下省略萬用字元。因此，完整的 `FROM S3Object` 子句相當於 `FROM S3Object[*] as S3Object`。如果您包含路徑，則必須也使用萬用字元。因此 `FROM S3Object` 和 `FROM S3Object[*].path` 兩者皆為有效的子句，但是 `FROM S3Object.path` 則否。

**Example**  
**範例**：  
*範例 \$11*  
此範例顯示使用下列資料集和查詢時的結果：  

```
{ "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"}
```
*範例 \$12*  
此範例顯示使用下列資料集和查詢時的結果：  

```
{ "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` 篩選資料列。 條件是具有布林值結果的表達式。僅限當條件評估為在結果中傳回 `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` 的某列第 *Nth* 欄，其中 *`N`* 是欄的位置。位置計算從 1 開始。例如，第一個欄位名稱為 `_1`，而第二個欄位名稱為 `_2`。

  您可以提及欄做為 `_N` 或 `alias._N`。例如，`_2` 和 `myAlias._2` 都是在 `SELECT` 清單和 `WHERE` 子句中提及欄的有效方法。
+ **欄標題** – 若 CSV 格式的物件擁有標頭列，則可將標頭用於 `SELECT` 清單和 `WHERE` 子句。尤其是，在 `SELECT` 和 `WHERE` 子句運算式中的傳統 SQL 運算式，您可以透過 `alias.column_name` 或 `column_name` 來提及欄。

### JSON
<a name="s3-select-sql-reference-attribute-access-json"></a>
+ **文件** – 您可存取 JSON 文件欄位做為 `alias.name`。您也可以存取巢狀欄位；例如 `alias.name1.name2.name3`。
+ **清單** – 您可使用以零為起始且含有 `[]` 運算子的索引來存取 JSON 清單中的元素。例如，您可以存取元素的第二個清單做為 `alias[1]`。您可以將存取清單元素與欄位相結合，例如，`alias.name1.name2[1].name3`。
+ **範例：**將此 JSON 物件做為範例資料集：

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

  *範例 \$11*

  下列查詢會傳回這些結果：

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

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

  *範例 \$12*

  下列查詢會傳回這些結果：

  ```
  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) CSV 格式的 Amazon S3 物件，內含指定欄標頭，且將 `FileHeaderInfo` 設為 `"Use"` 以進行查詢請求；或者 2) 含指定屬性且為 JSON 格式的 Amazon S3 物件。

*範例 \$11：*正在受到查詢的物件有標頭或屬性 `NAME`。
+ 以下運算式成功將值從物件傳回。因為沒有引號，所以查詢不區分大小寫。

  ```
  SELECT s.name from S3Object s
  ```
+ 以下運算式產生 400 錯誤 `MissingHeaderName`。因為有引號，所以查詢區分大小寫。

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

*範例 \$12：*要查詢的 Amazon S3 物件內含一個標頭或屬性 `NAME` 和另一個標頭或屬性 `name`。
+ 以下運算式產生 400 錯誤 `AmbiguousFieldName`。因為沒有引號，所以查詢不區分大小寫，但有兩個相符項目，因此會擲回錯誤。

  ```
  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) CSV 格式的 Amazon S3 物件，內含指定欄標頭，且將 `FileHeaderInfo` 設為 `"Use"` 以進行查詢請求；或者 2) 含指定屬性且為 JSON 格式的 Amazon S3 物件。

*範例：*正受到查詢的物件有名為 `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`*** ]