

# SELECT
<a name="select"></a>

0개 이상의 테이블에서 데이터 행을 검색합니다.

**참고**  
이 주제에서는 참조할 수 있는 요약 정보를 제공합니다. `SELECT` 및 SQL 언어에 대한 포괄적인 정보는 이 설명서에서 다루지 않습니다. Athena와 관련된 SQL 사용에 대한 자세한 내용은 [Amazon Athena의 SQL 쿼리에 대한 고려 사항 및 제한 사항](other-notable-limitations.md) 및 [Amazon Athena에서 SQL 쿼리 실행](querying-athena-tables.md) 단원을 참조하세요. 데이터베이스 생성, 테이블 생성 및 Athena의 테이블에서 `SELECT` 쿼리 실행에 대한 예제는 [시작하기](getting-started.md) 항목을 참조하세요.

## 시놉시스
<a name="synopsis"></a>

```
[ WITH with_query [, ...] ]
SELECT [ ALL | DISTINCT ] select_expression [, ...]
[ FROM from_item [, ...] ]
[ WHERE condition ]
[ GROUP BY [ ALL | DISTINCT ] grouping_element [, ...] ]
[ HAVING condition ]
[ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] select ]
[ ORDER BY expression [ ASC | DESC ] [ NULLS FIRST | NULLS LAST] [, ...] ]
[ OFFSET count [ ROW | ROWS ] ]
[ LIMIT [ count | ALL ] ]
```

**참고**  
SQL SELECT 문의 예약어는 큰따옴표로 묶어야 합니다. 자세한 내용은 [SQL SELECT 문에서 이스케이프할 예약어](reserved-words.md#list-of-reserved-words-sql-select) 섹션을 참조하세요.

## 파라미터
<a name="select-parameters"></a>

**[ WITH with\$1query [, ....] ]**  
`WITH`를 사용하여 중첩 쿼리를 평면화하거나 하위 쿼리를 단순화할 수 있습니다.  
Athena 엔진 버전 3부터 `WITH` 절을 사용하여 재귀 쿼리를 생성하는 작업이 지원됩니다. 최대 재귀 깊이는 10입니다.  
`WITH` 절은 쿼리에서 `SELECT` 목록에 선행하고 `SELECT` 쿼리 내에서 사용할 하나 이상의 하위 쿼리를 정의합니다.  
각각의 하위 쿼리는 `FROM` 절에서 참조할 수 있는 뷰 정의와 비슷한 임시 테이블을 정의합니다. 이러한 테이블은 쿼리를 실행할 때만 사용됩니다.  
`with_query` 구문은 다음과 같습니다.  

```
subquery_table_name [ ( column_name [, ...] ) ] AS (subquery)
```
위치:  
+  `subquery_table_name`은 `WITH` 절 하위 쿼리의 결과를 정의하는 임시 테이블의 고유한 이름입니다. 각각의 `subquery`에는 `FROM` 절에서 참조될 수 있는 테이블 이름이 있어야 합니다.
+  `column_name [, ...]`은 출력 열 이름의 선택적 목록입니다. 열 이름의 수는 `subquery`로 정의되는 열 개수보다 적거나 같아야 합니다.
+  `subquery`는 임의의 쿼리 설명문입니다.

**[ ALL \$1 DISTINCT ] select\$1expression**  
 `select_expression`는 선택하려는 행을 결정합니다. `select_expression`은 다음 형식 중 하나를 사용할 수 있습니다.  

```
expression [ [ AS ] column_alias ] [, ...]
```

```
row_expression.* [ AS ( column_alias [, ...] ) ]
```

```
relation.*
```

```
*
```
+ `expression [ [ AS ] column_alias ]` 구문은 출력 열을 지정합니다. 선택적 `[AS] column_alias` 구문은 출력에서 열에 사용할 사용자 지정 제목 이름을 지정합니다.
+ `row_expression.* [ AS ( column_alias [, ...] ) ]`의 경우에, `row_expression`은 임의의 데이터 유형 `ROW`의 표현식입니다. 행의 필드는 결과에 포함할 출력 열을 정의합니다.
+ `relation.*`의 경우, `relation`의 열이 결과에 포함됩니다. 이 구문에서는 열 별칭을 사용할 수 없습니다.
+ 별표 `*`는 모든 열이 결과 집합에 포함되도록 지정합니다.
+ 결과 집합에서 열의 순서는 select 표현식이 지정한 순서와 동일합니다. select 표현식이 여러 열을 반환하는 경우 열 순서는 소스 관계 또는 행 유형 표현식에 사용된 순서를 따릅니다.
+ 열 별칭을 지정하면 별칭이 기존 열 또는 행 필드 이름보다 우선합니다. select 표현식에 열 이름이 없는 경우 인덱스가 0인 익명 열 이름(`_col0`, `_col1`, `_col2, ...`)이 출력에 표시됩니다.
+  기본값은 `ALL`입니다. `ALL`을 사용하면 마치 생략된 것처럼 처리됩니다. 모든 열에 대한 모든 행이 선택되고 중복이 유지됩니다.
+ 열에 중복된 값이 포함되어 있는 경우 고유 값만 반환하려면 `DISTINCT`를 사용합니다.

**FROM from\$1item [, ...]**  
아래에 설명된 대로 `from_item`이 뷰, 조인 생성 또는 하위 쿼리가 될 수 있는 쿼리 입력을 나타냅니다.  
`from_item`은 다음 중 하나일 수 있습니다.  
+  `table_name [ [ AS ] alias [ (column_alias [, ...]) ] ]` 

  `table_name`이 행을 선택할 대상 테이블의 이름인 경우 `alias`는 `SELECT` 설명의 출력을 제공할 이름이고 `column_alias`는 지정된 `alias`에 대한 열을 정의합니다.
 **-또는-**   
+  `join_type from_item [ ON join_condition | USING ( join_column [, ...] ) ]` 

  여기에서 `join_type`은 다음 중 하나입니다.
  +  `[ INNER ] JOIN` 
  +  `LEFT [ OUTER ] JOIN` 
  +  `RIGHT [ OUTER ] JOIN` 
  +  `FULL [ OUTER ] JOIN` 
  +  `CROSS JOIN` 
  +  `ON join_condition | USING (join_column [, ...])` `join_condition`을 사용하면 여러 테이블의 조인 키에 열 이름을 지정할 수 있으며 `join_column`을 사용하려면 `join_column`가 두 테이블에 모두 존재해야 합니다.

**[ WHERE condition ]**  
사용자가 지정한 `condition`에 따라 결과를 필터링합니다. 여기서 `condition`에는 일반적으로 다음과 같은 구문이 있습니다.  

```
column_name operator value [[[AND | OR] column_name operator value] ...]
```
*연산자*는 비교 연산자(`=`, `>`, `<`, `>=`, `<=`, `<>`, `!=`) 중 하나일 수 있습니다.  
다음 하위 쿼리 표현식은 `WHERE`절에서 사용할 수도 있습니다.  
+ `[NOT] BETWEEN integer_A AND integer_B` – 다음 예시처럼 두 정수 사이의 범위를 지정합니다. 열 데이터 형식이 `varchar`인 경우 먼저 열을 정수로 변환해야 합니다.

  ```
  SELECT DISTINCT processid FROM "webdata"."impressions"
  WHERE cast(processid as int) BETWEEN 1500 and 1800
  ORDER BY processid
  ```
+ `[NOT] LIKE value` - 지정된 패턴을 검색합니다. 다음 예시와 같이 백분율 기호(`%`)를 와일드카드 문자로 사용할 수 있습니다.

  ```
  SELECT * FROM "webdata"."impressions"
  WHERE referrer LIKE '%.org'
  ```
+ `[NOT] IN (value[, value[, ...])` - 다음 예시와 같이 열에 사용 가능한 값 목록을 지정합니다.

  ```
  SELECT * FROM "webdata"."impressions"
  WHERE referrer IN ('example.com','example.net','example.org')
  ```

**[ GROUP BY [ ALL \$1 DISTINCT ] grouping\$1expressions [, ...] ]**  
`SELECT` 설명의 출력을 일치하는 값의 행으로 나눕니다.  
 `ALL` 및 `DISTINCT`는 중복되는 그룹화 집합이 각각 다른 출력 행을 생성할지 결정합니다. 생략된 경우, `ALL`로 간주됩니다.  
`grouping_expressions`를 사용하면 복합 그룹화 작업을 수행할 수 있습니다. 복합 그룹화(complex grouping) 연산을 수행하면 하나의 쿼리에 여러 집합을 집계해야 하는 분석을 수행할 수 있습니다.  
`grouping_expressions` 요소는 다음과 입력 열에서 수행되는 모든 함수(예: `SUM`, `AVG`, 또는 `COUNT`)일 수 있습니다.  
`GROUP BY` 식은 `SELECT` 설명 출력에 나타나지 않는 입력 열 이름별로 출력을 그룹화할 수 있습니다.  
모든 출력 식은 집계 함수이거나 `GROUP BY` 절에 있는 열이어야 합니다.  
단일 쿼리를 사용하여 여러 열 집합을 집계해야 하는 분석을 수행할 수 있습니다.  
Athena는 `GROUPING SETS`, `CUBE`, `ROLLUP`을 사용한 복합적 집계를 지원합니다. `GROUP BY GROUPING SETS`은 그룹화할 여러 열 목록을 지정합니다. `GROUP BY CUBE`은 주어진 열 집합에 대해 가능한 모든 그룹화 집합을 생성합니다. `GROUP BY ROLLUP`은 주어진 열 집합에 대해 가능한 모든 소계를 생성합니다. 복합 그룹화 연산은 입력 열로 구성된 표현식에 대해 그룹화를 지원하지 않습니다. 열 이름만 허용됩니다.  
흔히 `UNION ALL`을 사용해도 이러한 `GROUP BY` 작업과 동일한 결과를 얻을 수 있지만 `GROUP BY`를 사용하는 쿼리는 데이터를 한 번만 읽는 이점이 있는 데 비해 `UNION ALL`은 기본 데이터를 세 번 읽으며, 데이터 원본이 변경될 경우 일관성 없는 결과를 생성할 수 있습니다.

**[ HAVING condition ]**  
집계 함수 및 `GROUP BY` 절과 함께 사용됩니다. `condition`을 만족하지 않는 그룹을 제거하여 어떤 그룹을 선택할지 제어합니다. 이 필터링은 그룹과 집계 처리가 완료된 후 적용됩니다.

**[ \$1 UNION \$1 INTERSECT \$1 EXCEPT \$1 [ ALL \$1 DISTINCT ] union\$1query] ]**  
`UNION`, `INTERSECT`, `EXCEPT`는 둘 이상의 `SELECT` 문 결과를 하나의 쿼리로 결합합니다. `ALL` 또는 `DISTINCT`는 최종 결과 집합에 포함된 열의 고유성을 제어합니다.  
`UNION`은 첫 번째 쿼리의 결과 행을 두 번째 쿼리의 결과 행과 결합합니다. 중복된 항목을 제거하기 위해 `UNION`은 메모리를 소비하는 해시 테이블을 빌드합니다. 쿼리에서 중복 항목을 제거할 필요가 없는 경우 성능 향상을 위해 `UNION ALL`을 사용하는 것이 좋습니다. 다중 `UNION` 절은 괄호를 사용하여 처리 순서를 명시적으로 정의하지 않는 한 왼쪽에서 오른쪽으로 처리됩니다.  
`INTERSECT`는 첫 번째 쿼리와 두 번째 쿼리의 결과에 모두 존재하는 행만 반환합니다.  
`EXCEPT`는 두 번째 쿼리에서 찾은 행을 제외한 첫 번째 쿼리의 결과 행을 반환합니다.  
`ALL`은 동일한 행이라 하더라도 모든 행을 포함시킵니다.  
`DISTINCT`는 결합된 결과 집합에 고유한 행만 포함시킵니다.

**[ ORDER BY expression [ ASC \$1 DESC ] [ NULLS FIRST \$1 NULLS LAST] [, ...] ]**  
하나 이상의 출력 `expression`으로 결과 집합을 정렬합니다.  
절에 여러 식이 포함되어 있으면 결과 집합은 첫 번째 `expression`에 따라 정렬됩니다. 그리고 첫 번째 식에서 일치하는 값이 있는 행에 두 번째 `expression`이 적용되고, 세 번째도 동일하게 적용됩니다.  
각 `expression`은 `SELECT`의 출력 열을 지정하거나 위치별로 출력 열의 서수를 1부터 지정할 수 있습니다.  
`ORDER BY`는 `GROUP BY` 또는 `HAVING` 절 이후 마지막 단계로 평가됩니다. `ASC` 및 `DESC`는 결과를 오름차순이나 내림차순으로 정렬하도록 결정합니다. 기본적인 정렬 순서는 오름차순입니다(`ASC`). 오름차순 또는 내림차순 정렬 순서와 상관없이 기본 null 순서는 `NULLS LAST`입니다.

**[ OFFSET count [ ROW \$1 ROWS ] ]**  
`OFFSET` 절을 사용하여 결과 집합에서 여러 개의 선행 행을 삭제합니다. `ORDER BY` 절이 있는 경우 `OFFSET` 절은 정렬된 결과 집합에 대해 평가되며, 건너뛴 행이 삭제된 후에도 집합이 정렬된 상태로 유지됩니다. 쿼리에 `ORDER BY` 절이 없는 경우 삭제되는 행은 임의로 선택됩니다. `OFFSET`에 의해 지정된 수가 결과 집합의 크기와 같거나 더 크면 최종 결과는 비어 있습니다.

**LIMIT [ count \$1 ALL ]**  
결과 집합의 행 수를 `count`로 제한합니다. `LIMIT ALL`은 `LIMIT` 절 생략과 동일합니다. 쿼리에 `ORDER BY` 절이 없는 경우 결과는 임의입니다.

**TABLESAMPLE [ BERNOULLI \$1 SYSTEM ] (백분율)**  
샘플링 방법을 기반으로 테이블에서 행을 선택하는 선택적 연산자입니다.  
 `BERNOULLI`는 `percentage`의 확률로 테이블 샘플에 포함할 각 행을 선택합니다. 테이블의 모든 물리적 블록이 스캔되고 샘플 `percentage`와 실행 시간에 계산된 임의 값 사이의 비교를 기반으로 특정 행을 건너뜁니다.  
`SYSTEM`을 사용하면 테이블이 데이터의 논리적 세그먼트로 나뉘고 이 세분 수준에서 테이블이 샘플링됩니다.  
특정 세그먼트의 모든 행이 선택되거나 샘플 `percentage`와(과) 실행 시간에 계산된 임의 값 사이의 비교 결과에 따라 세그먼트를 건너뜁니다. `SYSTEM` 샘플링은 커넥터에 따라 다릅니다. 이 메서드는 독립적인 샘플링 확률을 보장하지 않습니다.

**[ UNNEST (array\$1or\$1map) [WITH ORDINALITY] ]**  
배열 또는 맵을 관계로 확장합니다. 배열은 하나의 열로 확장됩니다. 맵은 두 개의 열(*키*, *값*)로 확장됩니다.  
복수의 인수로 `UNNEST`를 사용할 수 있습니다. 이 경우 가장 큰 카디널리티 인수와 동일한 개수의 행이 있는 여러 열로 확장됩니다.  
다른 열은 null로 채워집니다.  
`WITH ORDINALITY` 절은 끝에 순서 열을 추가합니다.  
 `UNNEST`는 일반적으로 `JOIN`과 함께 사용되며 `JOIN` 왼쪽의 관계에서 열을 참조할 수 있습니다.

## Amazon S3의 소스 데이터에 대한 파일 위치 가져오기
<a name="select-path"></a>

테이블 행의 데이터에 대한 Amazon S3 파일 위치를 보려면 다음 예시처럼 `SELECT` 쿼리에 `"$path"`를 사용할 수 있습니다.

```
SELECT "$path" FROM "my_database"."my_table" WHERE year=2019;
```

이 쿼리는 다음과 같은 결과를 반환합니다.

```
s3://amzn-s3-demo-bucket/datasets_mytable/year=2019/data_file1.json
```

테이블의 데이터에 대한 S3 파일 이름 경로를 정렬된 고유 목록으로 반환하려면 다음 예시와 같이 `SELECT DISTINCT` 및 `ORDER BY`를 사용합니다.

```
SELECT DISTINCT "$path" AS data_source_file
FROM sampledb.elb_logs
ORDER By data_source_file ASC
```

경로가 없는 파일 이름만 반환하려면 다음 예시와 같이 `regexp_extract` 함수에 `"$path"`를 파라미터로 전달합니다.

```
SELECT DISTINCT regexp_extract("$path", '[^/]+$') AS data_source_file
FROM sampledb.elb_logs
ORDER By data_source_file ASC
```

특정 파일의 데이터를 반환하려면 다음 예시와 같이 `WHERE` 절에 파일을 지정합니다.

```
SELECT *,"$path" FROM my_database.my_table WHERE "$path" = 's3://amzn-s3-demo-bucket/my_table/my_partition/file-01.csv'
```

자세한 내용과 예시는 지식 센터 문서 [Athena 테이블의 행에 대한 Amazon S3 원본 파일을 확인하려면 어떻게 해야 합니까?](https://aws.amazon.com/premiumsupport/knowledge-center/find-s3-source-file-athena-table-row/)를 참조하세요.

**참고**  
Athena에서는 Hive 또는 Iceberg의 숨겨진 메타데이터 열 `$bucket`, `$file_modified_time`, `$file_size` 및 `$partition`을 보기에서 지원하지 않습니다.

## 작은따옴표의 이스케이프 처리
<a name="select-escaping"></a>

 작은따옴표를 이스케이프 처리하려면 다음 예제와 같이 작은따옴표 앞에 다른 작은따옴표를 추가합니다. 이를 큰따옴표와 혼동하지 마십시오.

```
Select 'O''Reilly'
```

**결과**  
`O'Reilly`

## 추가 리소스
<a name="select-additional-resources"></a>

Athena에서 `SELECT` 문 사용에 관한 자세한 내용은 다음 리소스를 참조하세요.


| 이에 대한 자세한 내용은 | 다음을 참조: | 
| --- | --- | 
| Athena에서 쿼리 실행 | [Amazon Athena에서 SQL 쿼리 실행](querying-athena-tables.md) | 
| SELECT를 사용해 테이블 생성 | [쿼리 결과에서 테이블 생성(CTAS)](ctas.md) | 
| SELECT 쿼리의 데이터를 다른 테이블에 삽입 | [INSERT INTO](insert-into.md) | 
| SELECT 문에서 내장 함수 사용  | [Amazon Athena의 함수](functions.md) | 
| SELECT 문에서 사용자가 정의한 함수 사용 | [사용자 정의 함수를 사용한 쿼리](querying-udf.md) | 
| 데이터 카탈로그 메타데이터 쿼리 | [AWS Glue Data Catalog 쿼리](querying-glue-catalog.md) | 