

# 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 명령만 지원합니다. `SELECT`에서 지원되는 ANSI 표준 절은 다음과 같습니다.


+ `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`으로 특정 행의 *N번째* 열을 참조할 수 있습니다(여기서 *`N`*은 열의 위치입니다). 위치 카운트는 1에서 시작합니다. 예를 들어, 첫 번째 열의 이름은 `_1`이고, 두 번째 열의 이름은 `_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>
+ **문서** – `alias.name`으로 JSON 문서 필드에 액세스할 수 있습니다. 중첩 필드에도 액세스할 수 있습니다(예: `alias.name1.name2.name3`).
+ ****목록 – `[]` 연산자가 있는 0 기반 인덱스를 사용하여 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}
      ]
  }
  ```

  *예제 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`이 있는 머리글 또는 속성이 하나 있고 `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) 열 머리글이 지정되어 있고 쿼리 요청에 대해 `FileHeaderInfo`가 `"Use"`으로 설정되어 있는 CSV 형식의 Amazon S3 객체 또는 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`*** ]