

# 쿼리 결과에서 테이블 생성(CTAS)
<a name="ctas"></a>

`CREATE TABLE AS SELECT`(CTAS) 쿼리는 다른 쿼리의 `SELECT` 문 결과로부터 Athena의 새 테이블을 만듭니다. Athena는 CTAS 문에서 생성한 데이터 파일을 Amazon S3의 지정된 위치에 저장합니다. 구문은 [CREATE TABLE AS](create-table-as.md) 단원을 참조하세요.

`CREATE TABLE AS`에서는 `CREATE TABLE` DDL 문을 `SELECT` DML 문과 결합하므로 기술적으로 DDL과 DML을 모두 포함합니다. 그러나 Service Quotas purposes 측면에서 Athena의 CTAS 쿼리는 DML로 처리됩니다. Athena에서 Service Quotas에 대한 자세한 내용은 [Service Quotas](service-limits.md) 섹션을 참조하세요.

CTAS 쿼리를 사용해 다음 작업을 수행할 수 있습니다.
+ 원리 데이터 세트를 반복적으로 쿼리하지 않고 쿼리 결과에서 한 번에 테이블을 생성합니다. 따라서 원시 데이터 세트를 더 쉽게 사용할 수 있습니다.
+ 쿼리 결과를 변환하고 테이블을 Apache Iceberg와 같은 다른 테이블 형식으로 마이그레이션합니다. 이렇게 하면 쿼리 성능이 개선되고 Athena 쿼리 비용이 줄어듭니다. 자세한 내용은 [Iceberg 테이블 생성](querying-iceberg-creating-tables.md) 섹션을 참조하세요.
+ 쿼리 결과를 Parquet 및 ORC 등과 같은 스토리지 형식으로 변환합니다. 이렇게 하면 쿼리 성능이 개선되고 Athena 쿼리 비용이 줄어듭니다. 자세한 내용은 [열 기반 스토리지 형식 사용](columnar-storage.md) 섹션을 참조하세요.
+ 필요한 데이터만 포함된 기존 테이블의 복사본을 생성합니다.

**Topics**
+ [CTAS 쿼리에 대한 고려 사항 및 제한 사항](ctas-considerations-limitations.md)
+ [CTAS 쿼리 생성](ctas-console.md)
+ [CTAS 예](ctas-examples.md)
+ [ETL에 CTAS 및 INSERT INTO 사용](ctas-insert-into-etl.md)
+ [100개 파티션 한도 문제 해결](ctas-insert-into.md)

# CTAS 쿼리에 대한 고려 사항 및 제한 사항
<a name="ctas-considerations-limitations"></a>

다음 섹션에서는 Athena에서 `CREATE TABLE AS SELECT`(CTAS) 쿼리를 사용할 때 유의해야 할 고려 사항과 제한 사항을 설명합니다.

## CTAS 쿼리 구문 알아보기
<a name="ctas-considerations-limitations-query-syntax"></a>

CTAS 쿼리 구문은 테이블 생성에 사용되는 `CREATE [EXTERNAL] TABLE`의 구문과 다릅니다. [CREATE TABLE AS](create-table-as.md)을(를) 참조하세요.

## 뷰와 CTAS 쿼리의 차이점
<a name="ctas-considerations-limitations-queries-vs-views"></a>

CTAS 쿼리는 Amazon S3의 지정된 위치에 새 데이터를 씁니다. 뷰는 어떤 데이터도 쓰지 않습니다.

## CTAS 쿼리 결과를 저장할 위치 지정
<a name="ctas-considerations-limitations-location-of-query-results"></a>

작업 그룹이 쿼리 결과 위치에 대한 [클라이언트 측 설정을 재정의](workgroups-settings-override.md)하는 경우 Athena는 `s3://amzn-s3-demo-bucket/tables/<query-id>/` 위치에 테이블을 생성합니다. 작업 그룹에 지정된 쿼리 결과 위치를 보려면 [작업 그룹 세부 정보를 조회](viewing-details-workgroups.md)하세요.

작업 그룹이 쿼리 결과 위치를 재정의하지 않으면 CTAS 쿼리에서 `WITH (external_location ='s3://amzn-s3-demo-bucket/')` 구문을 사용하여 CTAS 쿼리 결과가 저장되는 위치를 지정할 수 있습니다.

**참고**  
`external_location` 속성은 비어 있는 위치를 지정해야 합니다. CTAS 쿼리는 버킷의 경로 위치(접두사)가 비어 있는지 확인하고 해당 위치에 이미 데이터가 있는 경우 해당 데이터를 절대 덮어쓰지 않습니다. 동일한 위치를 다시 사용하려면 버킷의 키 접두사 위치에서 데이터를 삭제하세요.

`external_location` 구문을 생략하고 작업 그룹 설정을 사용하지 않으면 Athena는 쿼리 결과 위치에 대해 [클라이언트 측 설정](query-results-specify-location-console.md)을 사용하고 `s3://amzn-s3-demo-bucket/<Unsaved-or-query-name>/<year>/<month/<date>/tables/<query-id>/` 위치에 테이블을 생성합니다.

## 분리된 파일 찾기
<a name="ctas-considerations-limitations-locating-orphaned-files"></a>

`CTAS` 또는 `INSERT INTO` 문이 실패하는 경우 분리된 데이터 파일이 실패 또는 취소된 쿼리의 대상 데이터 위치에 남아 있을 가능성이 있습니다. 일부 경우 Athena가 쿼리의 대상 버킷에서 데이터를 삭제하지 않으므로 후속 쿼리에 부분 데이터가 포함될 수 있습니다.

검사 또는 삭제할 분리된 파일을 찾으려면 Athena에서 제공하는 데이터 매니페스트 파일을 사용하여 작성할 파일 목록을 추적할 수 있습니다. 드물지만 Athena 쿼리가 갑자기 실패한 경우 매니페스트 파일이 없을 수 있습니다. 대상 S3 위치를 수동으로 검사하여 분리된 파일을 찾을 수 있습니다. 자세한 내용은 [쿼리 출력 파일 식별](querying-finding-output-files.md#querying-identifying-output-files) 및 [DataManifestLocation](https://docs.aws.amazon.com/athena/latest/APIReference/API_QueryExecutionStatistics.html#athena-Type-QueryExecutionStatistics-DataManifestLocation)을 참조하세요.

Apache Iceberg를 사용하여 테이블의 원자성 트랜잭션을 달성하는 것이 좋습니다. 자세한 내용은 [Apache Iceberg 테이블 쿼리](querying-iceberg.md) 섹션을 참조하세요.

## ORDER BY 절은 무시된다는 점을 기억하세요.
<a name="ctas-considerations-limitations-order-by-ignored"></a>

CTAS 쿼리에서 Athena는 쿼리의 `SELECT` 부분에 있는 `ORDER BY` 절을 무시합니다.

SQL 사양(ISO 9075 Part 2)에 따라, `ORDER BY` 절을 바로 포함하는 쿼리 표현식에서만 쿼리 표현식에서 지정한 테이블의 행 순서가 보장됩니다. 어떤 경우든 SQL의 테이블은 내재적으로 정렬되지 않기 때문에 하위 쿼리에서 `ORDER BY`를 구현하면 쿼리가 잘못 수행되고 정렬된 출력을 얻을 수 없습니다. 따라서 Athena CTAS 쿼리에서는 데이터를 쓸 때 `ORDER BY` 절에서 지정한 순서가 유지되지 않을 수 있습니다.

## 쿼리 결과를 저장할 형식 선택
<a name="ctas-considerations-limitations-formats-for-query-results"></a>

CTAS 결과는 `PARQUET`, `ORC`, `AVRO`, `JSON` 및 `TEXTFILE`에 저장할 수 있습니다. CTAS `TEXTFILE` 형식에는 다중 문자 구분 기호가 지원되지 않습니다. 데이터 스토리지 형식을 지정하지 않으면 CTAS 쿼리 결과는 기본적으로 Parquet에 저장됩니다.

CTAS 쿼리를 실행할 때 형식 변환을 해석하기 위해 SerDe를 지정할 필요는 없습니다. [Example: Writing query results to a different format](ctas-examples.md#ctas-example-format)을(를) 참조하세요.

## 압축 형식 고려
<a name="ctas-considerations-limitations-compression-formats"></a>

`GZIP` 압축은 JSON 및 TEXTFILE 형식의 CTAS 쿼리 결과에 사용됩니다. Parquet의 경우 `GZIP` 또는 `SNAPPY`를 사용할 수 있으며 기본값은 `GZIP`입니다. ORC의 경우 `LZ4`, `SNAPPY`, `ZLIB` 또는 `ZSTD`를 사용할 수 있으며 기본값은 `ZLIB`입니다. 압축을 지정하는 CTAS 예제는 [Example: Specifying data storage and compression formats](ctas-examples.md#ctas-example-compression)단원을 참조하십시오. Athena의 압축에 대한 자세한 내용은 [Athena에서 압축 사용](compression-formats.md) 섹션을 참조하세요.

## 결과 분할 및 버킷팅
<a name="ctas-considerations-limitations-partition-and-bucket-limits"></a>

CTAS 쿼리의 결과 데이터를 분할하고 버킷화할 수 있습니다. 대상 테이블의 속성을 지정하려면 `WITH` 절 끝에 분할 및 버킷팅 조건자를 포함합니다. 자세한 내용은 [분할 및 버킷팅 사용](ctas-partitioning-and-bucketing.md) 및 [Example: Creating bucketed and partitioned tables](ctas-examples.md#ctas-example-bucketed)(을)를 참조하세요.

CTAS를 사용하여 분할된 테이블을 생성할 때 Athena의 쓰기 제한은 파티션 100개입니다. 100개 파티션 제한을 해결하는 방법에 대한 자세한 내용은 [CTAS 및 INSERT INTO를 사용하여 100개 파티션 한도 문제 해결](ctas-insert-into.md) 단원을 참조하세요.

## 결과 암호화
<a name="ctas-considerations-limitations-encryption"></a>

Amazon S3에서 다른 쿼리 결과를 암호화하는 것과 유사한 방식으로 Athena에서 CTAS 쿼리 결과를 암호화할 수 있습니다. 자세한 내용은 [Amazon S3에 저장된 Athena 쿼리 결과 암호화](encrypting-query-results-stored-in-s3.md) 섹션을 참조하세요.

## 예상 버킷 소유자 설정은 CTAS에는 적용되지 않습니다.
<a name="ctas-considerations-limitations-expected-bucket-owner"></a>

CTAS 문의 경우 예상 버킷 소유자 설정이 Amazon S3의 대상 테이블 위치에 적용되지 않습니다. 예상 버킷 소유자 설정은 Athena 쿼리 결과에 대해 지정한 Amazon S3 출력 위치에만 적용됩니다. 자세한 내용은 [Athena 콘솔을 사용하여 쿼리 결과 위치 지정](query-results-specify-location-console.md) 섹션을 참조하세요.

## 열 데이터 형식이 유지됨
<a name="ctas-considerations-limitations-data-types"></a>

CTAS 쿼리의 열 데이터 유형은 원본 쿼리에 지정된 유형과 동일합니다.

# Athena 콘솔에서 CTAS 쿼리 생성
<a name="ctas-console"></a>

Athena 콘솔을 사용하면 다른 쿼리에서 CTAS 쿼리를 생성할 수 있습니다.<a name="ctas-create-from-query"></a>

**다른 쿼리에서 CTAS 쿼리를 생성하려면**

1. Athena 콘솔 쿼리 편집기에서 쿼리를 실행합니다.

1. 쿼리 편집기 하단에서 **생성(Create)** 옵션을 선택한 다음 **쿼리에서 테이블(Table from query)**을 선택합니다.

1. **Create table as select** 양식에서 다음과 같이 필드를 작성합니다.

   1. **Table name**(테이블 이름)에는 새 테이블의 이름을 입력합니다. 소문자와 밑줄만 사용합니다(예: `my_select_query_parquet`).

   1. **Database configuration**(데이터베이스 구성)에는 기존 데이터베이스를 선택하거나 데이터베이스를 생성하는 옵션을 사용합니다.

   1. (선택 사항) **Result configuration**(결과 구성)의 **Location of CTAS query results**(CTAS 쿼리 결과 위치)에서는 작업 그룹 쿼리 결과 위치 설정에 따라 이 옵션이 재정의되지 않으면 다음 중 하나를 수행합니다.
      + 검색 상자에 기존 S3 위치의 경로를 입력하거나 **Browse S3**(S3 찾아보기)를 선택하여 목록에서 위치를 선택합니다.
      + **View**(보기)를 선택하여 기존 버킷에 대한 자세한 내용을 보고 버킷을 선택하거나 자체 설정으로 생성할 수 있는 Amazon S3 콘솔의 **Buckets**(버킷) 페이지를 엽니다.

      데이터가 출력될 Amazon S3의 빈 위치를 지정해야 합니다. 지정한 위치에 데이터가 이미 있는 경우 쿼리가 오류와 함께 실패합니다.

      작업 그룹 쿼리 결과 위치 설정에 따라 이 위치 설정이 재정의되는 경우 Athena에서는 위치 `s3://amzn-s3-demo-bucket/tables/query_id/`에 테이블을 생성합니다.

   1. **Data format**(데이터 형식)에는 데이터의 형식을 지정합니다.
      + **Table type**(테이블 유형) – Athena의 기본 테이블 유형은 Apache Hive입니다.
      + **File format**(파일 형식) - CSV, TSV, JSON, Parquet 또는 ORC와 같은 옵션 중에서 선택합니다. Parquet 및 ORC 형식에 대한 자세한 내용은 [열 기반 스토리지 형식 사용](columnar-storage.md) 섹션을 참조하세요.
      + **Write compression**(쓰기 압축) – (선택 사항) 압축 형식을 선택합니다. Athena는 여러 압축 형식을 사용하는 테이블에서 데이터를 읽는 것을 비롯하여, 데이터 읽기 및 쓰기를 위한 다양한 압축 형식을 지원합니다. 예를 들어 Athena는 일부 Parquet 파일이 Snappy로 압축되고 다른 Parquet 파일이 GZIP으로 압축된 경우 Parquet 파일 형식을 사용하는 테이블의 데이터를 성공적으로 읽을 수 있습니다. ORC, 텍스트 파일, JSON 스토리지 형식에도 동일한 원칙이 적용됩니다. 자세한 내용은 [Athena에서 압축 사용](compression-formats.md) 섹션을 참조하세요.
      + **Partitions**(파티션) – (선택 사항) 파티셔닝하려는 열을 선택합니다. 데이터를 파티셔닝하면 각 쿼리에서 스캔하는 데이터의 양이 제한되어 성능이 향상되고 비용이 절감됩니다. 어떤 키를 기준으로도 데이터를 분할할 수 있습니다. 자세한 내용은 [데이터 파티셔닝](partitions.md) 섹션을 참조하세요.
      + **Buckets**(버킷) – (선택 사항) 버킷팅하려는 열을 선택합니다. 버킷팅은 단일 파티션 내에서 특정 열을 기준으로 데이터를 그룹화하는 기법입니다. 이러한 열을 버킷 키라고 합니다. 관련 데이터를 단일 버킷(파티션 내 파일)으로 그룹화하면 Athena에서 스캔하는 데이터의 양이 대폭 감소하여 쿼리 성능이 향상되고 비용이 절감됩니다. 자세한 내용은 [분할 및 버킷팅 사용](ctas-partitioning-and-bucketing.md) 섹션을 참조하세요.

   1. **Preview table query**(미리 보기 테이블 쿼리)의 경우 쿼리를 검토합니다. 쿼리 구문은 [CREATE TABLE AS](create-table-as.md) 단원을 참조하세요.

   1. **테이블 생성**을 선택합니다.

Athena 콘솔에는 CTAS 쿼리를 생성하는 데에도 사용할 수 있는 SQL 템플릿이 있습니다.<a name="ctas-create-new"></a>

**템플릿을 사용하여 CTAS 쿼리를 생성하는 방법**

`CREATE TABLE AS SELECT` 템플릿을 사용하여 쿼리 편집기에서 CTAS 쿼리를 생성합니다.

1. Athena 콘솔에서 **테이블 및 뷰(Tables and views)** 옆에 있는 **테이블 생성(Create table)**을 선택한 다음 **CREATE TABLE AS SELECT**를 선택합니다. 그러면 쿼리 편집기가 자리 표시자 값이 있는 CTAS 쿼리로 채워집니다.

1. 쿼리 편집기에서 필요에 따라 쿼리를 편집합니다. 쿼리 구문은 [CREATE TABLE AS](create-table-as.md) 단원을 참조하세요.

1. **Run(실행)**을 선택합니다.

예시는 [CTAS 쿼리 예제](ctas-examples.md) 섹션을 참조하세요.



# CTAS 쿼리 예제
<a name="ctas-examples"></a>

다음 예제를 사용하여 CTAS 쿼리를 생성합니다. CTAS 구문에 대한 자세한 정보는 [CREATE TABLE AS](create-table-as.md) 단원을 참조하세요.

이 섹션의 내용: 
+  [Example: Duplicating a table by selecting all columns](#ctas-example-dupe-table) 
+  [Example: Selecting specific columns from one or more tables](#ctas-example-specify-columns) 
+  [Example: Creating an empty copy of an existing table](#ctas-example-empty-table) 
+  [Example: Specifying data storage and compression formats](#ctas-example-compression) 
+  [Example: Writing query results to a different format](#ctas-example-format) 
+  [Example: Creating unpartitioned tables](#ctas-example-unpartitioned) 
+  [Example: Creating partitioned tables](#ctas-example-partitioned) 
+  [Example: Creating bucketed and partitioned tables](#ctas-example-bucketed) 
+  [Example: Creating an Iceberg table with Parquet data](#ctas-example-iceberg-parquet) 
+  [Example: Creating an Iceberg table with Avro data](#ctas-example-iceberg-avro) 
+  [Example: Creating an S3 table using CTAS](#ctas-example-s3-table) 

**Example 예제: 모든 열을 선택하여 테이블 복제**  
다음 예제에서는 테이블의 모든 열을 복사해 테이블을 만듭니다.  

```
CREATE TABLE new_table AS 
SELECT * 
FROM old_table;
```
동일한 예제의 다음 변형에서 `SELECT` 문에는 `WHERE` 절이 포함되어 있습니다. 이 경우, 쿼리는 테이블에서 `WHERE` 절을 충족하는 행만 선택합니다.  

```
CREATE TABLE new_table AS 
SELECT * 
FROM old_table 
WHERE condition;
```

**Example 예제: 하나 이상의 테이블에서 특정 열 선택**  
다음 예제에서는 다른 테이블의 열 세트에 대해 실행할 새 쿼리를 생성합니다.  

```
CREATE TABLE new_table AS 
SELECT column_1, column_2, ... column_n 
FROM old_table;
```
동일한 예제의 이번 변형에서는 여러 테이블의 특정 열을 바탕으로 새 테이블을 생성합니다.  

```
CREATE TABLE new_table AS
SELECT column_1, column_2, ... column_n 
FROM old_table_1, old_table_2, ... old_table_n;
```

**Example 예제: 기존 테이블의 빈 복사본 생성**  
다음 예제에서는 `WITH NO DATA`를 사용해 비어 있지만 원본 테이블과 스키마가 동일한 새 테이블을 생성합니다.  

```
CREATE TABLE new_table 
AS SELECT * 
FROM old_table
WITH NO DATA;
```

**Example 예제: 데이터 스토리지 및 압축 형식 지정**  
CTAS를 사용하면 한 스토리지 형식의 소스 테이블을 사용하여 스토리지 형식이 다른 또 다른 테이블을 만들 수 있습니다.  
`format` 속성을 사용하여 `ORC`, `PARQUET`, `AVRO`, `JSON` 또는 `TEXTFILE`을 새 테이블의 스토리지 형식으로 지정합니다.  
`PARQUET`, `ORC`, `TEXTFILE` 및 `JSON` 스토리지 형식의 경우 `write_compression` 속성을 사용하여 새 테이블의 데이터에 대한 압축 형식을 지정합니다. 각 파일 형식에서 지원하는 압축 유형에 대한 자세한 내용은 [Athena에서 압축 사용](compression-formats.md) 섹션을 참조하세요.  
다음 예제에서는 `new_table` 테이블의 데이터를 Parquet 형식으로 Snappy 압축을 사용하여 저장하도록 지정합니다. Parquet의 기본 압축은 `GZIP`입니다.  

```
CREATE TABLE new_table
WITH (
      format = 'Parquet',
      write_compression = 'SNAPPY')
AS SELECT *
FROM old_table;
```
다음 예제에서는 `new_table` 테이블의 데이터를 ORC 형식으로 Snappy 압축을 사용하여 저장하도록 지정합니다. ORC의 기본 압축은 ZLIB입니다.  

```
CREATE TABLE new_table
WITH (format = 'ORC',
      write_compression = 'SNAPPY')
AS SELECT *
FROM old_table ;
```
다음 예제에서는 `new_table` 테이블의 데이터를 텍스트 파일 형식으로 Snappy 압축을 사용하여 저장하도록 지정합니다. 텍스트 파일과 JSON 형식 모두의 기본 압축은 GZIP입니다.  

```
CREATE TABLE new_table
WITH (format = 'TEXTFILE',
      write_compression = 'SNAPPY')
AS SELECT *
FROM old_table ;
```

**Example 예제: 쿼리 결과를 다른 형식으로 쓰기**  
다음 CTAS 쿼리는 CSV 또는 다른 형식으로 저장할 수 있는 모든 레코드를 `old_table`에서 선택하고 ORC 형식으로 Amazon S3에 저장된 기본 데이터로 새 테이블을 만듭니다.  

```
CREATE TABLE my_orc_ctas_table
WITH (
      external_location = 's3://amzn-s3-demo-bucket/my_orc_stas_table/',
      format = 'ORC')
AS SELECT * 
FROM old_table;
```

**Example 예제: 분할되지 않은 테이블 생성**  
다음 예제에서는 분할되지 않은 테이블을 생성합니다. 테이블 데이터가 다른 형식으로 저장됩니다. 이러한 예제 중 일부에서는 외부 위치를 지정합니다.  
다음 예제에서는 결과를 텍스트 파일로 저장하는 CTAS 쿼리를 생성합니다.  

```
CREATE TABLE ctas_csv_unpartitioned 
WITH (
     format = 'TEXTFILE', 
     external_location = 's3://amzn-s3-demo-bucket/ctas_csv_unpartitioned/') 
AS SELECT key1, name1, address1, comment1
FROM table1;
```
다음 예제에서는 결과가 Parquet에 저장되고 기본 결과 위치가 사용됩니다.  

```
CREATE TABLE ctas_parquet_unpartitioned 
WITH (format = 'PARQUET') 
AS SELECT key1, name1, comment1
FROM table1;
```
다음 쿼리에서는 테이블이 JSON으로 저장되고 원본 테이블 결과에서 특정 열을 선택합니다.  

```
CREATE TABLE ctas_json_unpartitioned 
WITH (
     format = 'JSON',  
     external_location = 's3://amzn-s3-demo-bucket/ctas_json_unpartitioned/') 
AS SELECT key1, name1, address1, comment1
FROM table1;
```
다음 예제에서 형식은 ORC입니다.  

```
CREATE TABLE ctas_orc_unpartitioned 
WITH (
     format = 'ORC') 
AS SELECT key1, name1, comment1 
FROM table1;
```
다음 예제에서 형식은 Avro입니다.  

```
CREATE TABLE ctas_avro_unpartitioned 
WITH (
     format = 'AVRO', 
     external_location = 's3://amzn-s3-demo-bucket/ctas_avro_unpartitioned/') 
AS SELECT key1, name1, comment1
FROM table1;
```

**Example 예제: 분할된 테이블 생성**  
다음 예제에서는 `partitioned_by` 및 `WITH` 절의 기타 속성을 사용하여 다른 스토리지 형식으로 분할된 테이블에 대한 `CREATE TABLE AS SELECT` 쿼리를 보여줍니다. 구문은 [CTAS 테이블 속성](create-table-as.md#ctas-table-properties) 단원을 참조하세요. 분할할 열 선택에 대한 자세한 정보는 [분할 및 버킷팅 사용](ctas-partitioning-and-bucketing.md) 단원을 참조하세요.  
`SELECT` 문의 열 목록 끝에 파티션 열을 나열합니다. 둘 이상의 열을 기준으로 분할할 수 있으며 최대 100개의 고유한 파티션과 버킷 조합을 가질 수 있습니다. 예를 들어 버킷이 지정되지 않은 경우 100개의 파티션을 가질 수 있습니다.

```
CREATE TABLE ctas_csv_partitioned 
WITH (
     format = 'TEXTFILE',  
     external_location = 's3://amzn-s3-demo-bucket/ctas_csv_partitioned/', 
     partitioned_by = ARRAY['key1']) 
AS SELECT name1, address1, comment1, key1
FROM tables1;
```

```
CREATE TABLE ctas_json_partitioned 
WITH (
     format = 'JSON', 
     external_location = 's3://amzn-s3-demo-bucket/ctas_json_partitioned/', 
     partitioned_by = ARRAY['key1']) 
AS select name1, address1, comment1, key1 
FROM table1;
```

**Example 예제: 버킷팅 및 분할된 테이블 생성**  
다음 예제는 Amazon S3에 쿼리 결과를 저장하기 위해 분할 및 버킷팅을 둘 다 사용하는 `CREATE TABLE AS SELECT` 쿼리를 보여줍니다. 테이블 결과가 다른 열을 기준으로 분할 및 버킷팅됩니다. Athena는 최대 100개의 고유한 파티션 및 버킷 조합을 지원합니다. 예를 들어 5개의 버킷이 있는 테이블을 생성하는 경우 각각 5개의 버킷이 있는 20개의 파티션이 지원됩니다. 구문은 [CTAS 테이블 속성](create-table-as.md#ctas-table-properties) 단원을 참조하세요.  
버킷팅할 열 선택에 대한 자세한 정보는 [분할 및 버킷팅 사용](ctas-partitioning-and-bucketing.md) 단원을 참조하세요.  

```
CREATE TABLE ctas_avro_bucketed 
WITH (
      format = 'AVRO', 
      external_location = 's3://amzn-s3-demo-bucket/ctas_avro_bucketed/', 
      partitioned_by = ARRAY['nationkey'], 
      bucketed_by = ARRAY['mktsegment'], 
      bucket_count = 3) 
AS SELECT key1, name1, address1, phone1, acctbal, mktsegment, comment1, nationkey 
FROM table1;
```

**Example 예: Parquet 데이터를 사용하여 Iceberg 테이블 생성**  
다음 예에서는 Parquet 데이터 파일을 사용하여 Iceberg 테이블을 생성합니다. 파일은 `table1`의 `dt` 열을 사용하여 월별로 분할됩니다. 이 예에서는 테이블의 모든 브랜치에 기본적으로 10개의 스냅샷이 보존되도록 테이블의 보존 속성을 업데이트합니다. 지난 7일 이내의 스냅샷도 유지됩니다. Athena에서 Iceberg 테이블 속성에 대한 자세한 내용은 [테이블 속성 지정](querying-iceberg-creating-tables.md#querying-iceberg-table-properties) 섹션을 참조하세요.  

```
CREATE TABLE ctas_iceberg_parquet
WITH (table_type = 'ICEBERG',
      format = 'PARQUET', 
      location = 's3://amzn-s3-demo-bucket/ctas_iceberg_parquet/', 
      is_external = false,
      partitioning = ARRAY['month(dt)'],
      vacuum_min_snapshots_to_keep = 10,
      vacuum_max_snapshot_age_seconds = 604800
   ) 
AS SELECT key1, name1, dt FROM table1;
```

**Example 예: Avro 데이터를 사용하여 Iceberg 테이블 생성**  
다음 예에서는 `key1`에 의해 분할된 Avro 데이터 파일을 사용하여 Iceberg 테이블을 생성합니다.  

```
CREATE TABLE ctas_iceberg_avro
WITH ( format = 'AVRO', 
       location = 's3://amzn-s3-demo-bucket/ctas_iceberg_avro/', 
       is_external = false,
       table_type = 'ICEBERG',
       partitioning = ARRAY['key1']) 
AS SELECT key1, name1, date FROM table1;
```

**Example 예: CTAS를 사용하여 S3 Table 생성**  
다음 예제에서는 CTAS를 사용하여 새 S3 Table을 생성합니다. 위치 속성은 생략되며 `table_type`의 기본값은 `ICEBERG`입니다.  

```
CREATE TABLE "s3tablescatalog/amzn-s3-demo-bucket"."namespace"."s3-table-name"
WITH (
    format = 'PARQUET'
)
AS SELECT *
FROM source_table;
```
일반 Iceberg 테이블과 동일한 구문으로 파티셔닝, 버킷팅과 같은 다른 모든 Iceberg 테이블 속성을 지정할 수 있습니다.

# ETL 및 데이터 분석에 CTAS 및 INSERT INTO 사용
<a name="ctas-insert-into-etl"></a>

Athena에서 Create Table as Select([CTAS](ctas.md)) 및 [INSERT INTO](insert-into.md) 문을 사용하면 데이터 처리를 위해 Amazon S3에 데이터를 추출, 변환 및 로드(ETL)할 수 있습니다. 이 주제에서는 이러한 문을 사용하여 데이터 세트를 분할하고 열 기반 데이터 형식으로 변환함으로써 데이터 분석에 최적화되도록 하는 방법을 보여줍니다.

CTAS 문은 표준 [SELECT](select.md) 쿼리를 사용하여 새 테이블을 생성합니다. CTAS 문을 사용하여 분석할 데이터의 하위 세트를 만들 수 있습니다. 하나의 CTAS 문에서, 데이터를 분할하고 압축을 지정하고 데이터를 Apache Parquet 또는 Apache ORC와 같은 열 기반 형식으로 변환할 수 있습니다. CTAS 쿼리를 실행하면 생성한 테이블 및 파티션은 [AWS Glue Data Catalog](https://aws.amazon.com/glue)에 자동으로 추가됩니다. 이렇게 하면 생성한 새 테이블 및 파티션을 후속 쿼리에 즉시 사용할 수 있습니다.

INSERT INTO 문은 원본 테이블에서 실행되는 SELECT 쿼리 문을 기반으로 대상 테이블에 새 행을 삽입합니다. INSERT INTO 문을 사용하면 CTAS가 지원하는 모든 변환을 사용하여 CSV 형식의 원본 테이블 데이터를 대상 테이블 데이터로 변환하고 로드할 수 있습니다.

## 개요
<a name="ctas-insert-into-etl-overview"></a>

Athena에서 CTAS 문을 사용하여 데이터의 초기 배치 변환을 수행합니다. 그런 다음, 여러 INSERT INTO 문을 사용하여 CTAS 문에 의해 생성된 테이블에 증분 업데이트를 만듭니다.

**단계**
+ [1단계: 원본 데이터 집합을 기반으로 테이블 생성](#ctas-insert-into-etl-step-1-create-a-table-based-on-the-original-dataset)
+  [2단계: CTAS를 사용하여 데이터 분할, 변환 및 압축](#ctas-insert-into-etl-step-2-use-ctas-to-partition-convert-and-compress-the-data) 
+  [3단계: INSERT INTO를 사용하여 데이터 추가](#ctas-insert-into-etl-step-3-use-insert-into-to-add-data) 
+  [4단계: 성능 및 비용 차이 측정](#ctas-insert-into-etl-step-4-measure-performance-and-cost-differences) 

## 1단계: 원본 데이터 집합을 기반으로 테이블 생성
<a name="ctas-insert-into-etl-step-1-create-a-table-based-on-the-original-dataset"></a>

이 주제의 예제에서는 공개적으로 이용 가능한 [NOAA Global Historical Climatology Network Daily(GHCN-D)](https://registry.opendata.aws/noaa-ghcn/) 데이터 집합의 Amazon S3 읽기 가능 하위 집합을 사용합니다. Amazon S3의 데이터에는 다음과 같은 특성이 있습니다.

```
Location: s3://aws-bigdata-blog/artifacts/athena-ctas-insert-into-blog/
Total objects: 41727
Size of CSV dataset: 11.3 GB
Region: us-east-1
```

원본 데이터는 파티션 없이 Amazon S3에 저장됩니다. 데이터는 다음과 유사한 파일에서 CSV 형식입니다.

```
2019-10-31 13:06:57  413.1 KiB artifacts/athena-ctas-insert-into-blog/2010.csv0000
2019-10-31 13:06:57  412.0 KiB artifacts/athena-ctas-insert-into-blog/2010.csv0001
2019-10-31 13:06:57   34.4 KiB artifacts/athena-ctas-insert-into-blog/2010.csv0002
2019-10-31 13:06:57  412.2 KiB artifacts/athena-ctas-insert-into-blog/2010.csv0100
2019-10-31 13:06:57  412.7 KiB artifacts/athena-ctas-insert-into-blog/2010.csv0101
```

이 샘플의 파일 크기는 상대적으로 작습니다. 파일을 더 큰 파일로 병합하면 총 파일 수를 줄일 수 있으므로 쿼리 성능이 향상됩니다. CTAS 및 INSERT INTO 문을 사용하여 쿼리 성능을 개선할 수 있습니다.

**샘플 데이터 세트를 기반으로 데이터베이스 및 테이블을 생성하려면**

1. Athena 콘솔에서 **미국 동부(버지니아 북부)(US East (N. Virginia))** AWS 리전을 선택합니다. `us-east-1`에서 이 자습서의 모든 쿼리를 실행합니다.

1. Athena 쿼리 편집기에서 [CREATE DATABASE](create-database.md) 명령을 실행하여 데이터베이스를 생성합니다.

   ```
   CREATE DATABASE blogdb
   ```

1. 다음 문을 실행하여 [테이블을 생성](create-table.md)합니다.

   ```
   CREATE EXTERNAL TABLE `blogdb`.`original_csv` (
     `id` string,
     `date` string,
     `element` string,
     `datavalue` bigint,
     `mflag` string,
     `qflag` string,
     `sflag` string,
     `obstime` bigint)
   ROW FORMAT DELIMITED
     FIELDS TERMINATED BY ','
   STORED AS INPUTFORMAT
     'org.apache.hadoop.mapred.TextInputFormat'
   OUTPUTFORMAT
     'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
   LOCATION
     's3://aws-bigdata-blog/artifacts/athena-ctas-insert-into-blog/'
   ```

## 2단계: CTAS를 사용하여 데이터 분할, 변환 및 압축
<a name="ctas-insert-into-etl-step-2-use-ctas-to-partition-convert-and-compress-the-data"></a>

테이블을 생성한 후에는 단일 [CTAS](ctas.md) 문을 사용하여 데이터를 Snappy 압축을 사용하는 Parquet 형식으로 변환하고 연도별로 데이터를 분할할 수 있습니다.

1단계에서 생성한 테이블에는 날짜 형식이 `YYYYMMDD`(예: `20100104`)인 `date` 필드가 있습니다. 새 테이블이 `year`에 분할되므로 다음 절차의 샘플 문은 Presto 함수 `substr("date",1,4)`을 사용하여 `date` 필드에서 `year` 값을 추출합니다.

**연도별로 분할하기 위해 데이터를 Snappy 압축을 사용하는 Parquet 형식으로 변환하려면**
+ 다음 CTAS 문을 실행하여 *버킷*을 Amazon S3 버킷 위치로 바꿉니다.

  ```
  CREATE table new_parquet
  WITH (format='PARQUET',
  parquet_compression='SNAPPY',
  partitioned_by=array['year'],
  external_location = 's3://amzn-s3-demo-bucket/optimized-data/')
  AS
  SELECT id,
           date,
           element,
           datavalue,
           mflag,
           qflag,
           sflag,
           obstime,
           substr("date",1,4) AS year
  FROM original_csv
  WHERE cast(substr("date",1,4) AS bigint) >= 2015
          AND cast(substr("date",1,4) AS bigint) <= 2019
  ```
**참고**  
이 예제에서 생성한 테이블에는 2015년부터 2019년까지의 데이터만 포함됩니다. 3단계에서는 INSERT INTO 명령을 사용하여 이 테이블에 새 데이터를 추가합니다.

쿼리가 완료되면 다음 절차를 사용하여 CTAS 문에서 지정한 Amazon S3 위치의 출력을 확인합니다.

**CTAS 문에 의해 생성된 파티션 및 Parquet 파일을 확인하려면**

1. 생성된 파티션을 표시하려면 다음 AWS CLI 명령을 실행합니다. 끝에 슬래시(/)가 있어야 합니다.

   ```
   aws s3 ls s3://amzn-s3-demo-bucket/optimized-data/
   ```

   출력이 파티션에 표시됩니다.

   ```
         PRE year=2015/
         PRE year=2016/
         PRE year=2017/
         PRE year=2018/
         PRE year=2019/
   ```

1. Parquet 파일을 확인하려면 다음 명령을 실행합니다. 출력을 처음 5개의 결과로 제한하는 `|` *head -5* 옵션은 Windows에서 사용할 수 없습니다.

   ```
   aws s3 ls s3://amzn-s3-demo-bucket/optimized-data/ --recursive --human-readable | head -5
   ```

   다음과 유사하게 출력됩니다.

   ```
   2019-10-31 14:51:05    7.3 MiB optimized-data/year=2015/20191031_215021_00001_3f42d_1be48df2-3154-438b-b61d-8fb23809679d
   2019-10-31 14:51:05    7.0 MiB optimized-data/year=2015/20191031_215021_00001_3f42d_2a57f4e2-ffa0-4be3-9c3f-28b16d86ed5a
   2019-10-31 14:51:05    9.9 MiB optimized-data/year=2015/20191031_215021_00001_3f42d_34381db1-00ca-4092-bd65-ab04e06dc799
   2019-10-31 14:51:05    7.5 MiB optimized-data/year=2015/20191031_215021_00001_3f42d_354a2bc1-345f-4996-9073-096cb863308d
   2019-10-31 14:51:05    6.9 MiB optimized-data/year=2015/20191031_215021_00001_3f42d_42da4cfd-6e21-40a1-8152-0b902da385a1
   ```

## 3단계: INSERT INTO를 사용하여 데이터 추가
<a name="ctas-insert-into-etl-step-3-use-insert-into-to-add-data"></a>

2단계에서는 CTAS를 사용하여 2015년부터 2019년까지 파티션이 있는 테이블을 생성했습니다. 하지만 원본 데이터 세트에는 2010년부터 2014년까지의 데이터도 포함되어 있습니다. 이제 [INSERT INTO](insert-into.md) 문을 사용하여 해당 데이터를 추가합니다.

**하나 이상의 INSERT INTO 문을 사용하여 테이블에 데이터를 추가하려면**

1. WHERE 절에 2015년 이전의 연도를 지정하여 다음 INSERT INTO 명령을 실행합니다.

   ```
   INSERT INTO new_parquet
   SELECT id,
            date,
            element,
            datavalue,
            mflag,
            qflag,
            sflag,
            obstime,
            substr("date",1,4) AS year
   FROM original_csv
   WHERE cast(substr("date",1,4) AS bigint) < 2015
   ```

1. 다음 구문을 사용하여 `aws s3 ls` 명령을 다시 실행합니다.

   ```
   aws s3 ls s3://amzn-s3-demo-bucket/optimized-data/
   ```

   출력이 새 파티션에 표시됩니다.

   ```
         PRE year=2010/
         PRE year=2011/
         PRE year=2012/
         PRE year=2013/
         PRE year=2014/
         PRE year=2015/
         PRE year=2016/
         PRE year=2017/
         PRE year=2018/
         PRE year=2019/
   ```

1. Parquet 형식에서 압축 및 열 기반 스토리지를 사용하여 얻은 데이터 세트의 크기 감소를 확인하려면 다음 명령을 실행합니다.

   ```
   aws s3 ls s3://amzn-s3-demo-bucket/optimized-data/ --recursive --human-readable --summarize
   ```

   다음 결과는 Snappy 압축을 사용하는 Parquet 형식으로 처리한 후 데이터 세트의 크기가 1.2GB임을 보여줍니다.

   ```
   ...
   2020-01-22 18:12:02 2.8 MiB optimized-data/year=2019/20200122_181132_00003_nja5r_f0182e6c-38f4-4245-afa2-9f5bfa8d6d8f
   2020-01-22 18:11:59 3.7 MiB optimized-data/year=2019/20200122_181132_00003_nja5r_fd9906b7-06cf-4055-a05b-f050e139946e
   Total Objects: 300
        Total Size: 1.2 GiB
   ```

1. 더 많은 CSV 데이터가 원본 테이블에 추가되면 INSERT INTO 문을 사용하여 해당 데이터를 Parquet 테이블에 추가할 수 있습니다. 예를 들어 2020년에 대한 새 데이터가 있는 경우 다음 INSERT INTO 문을 실행할 수 있습니다. INSERT INTO 문은 데이터 및 관련 파티션을 `new_parquet` 테이블에 추가합니다.

   ```
   INSERT INTO new_parquet
   SELECT id,
            date,
            element,
            datavalue,
            mflag,
            qflag,
            sflag,
            obstime,
            substr("date",1,4) AS year
   FROM original_csv
   WHERE cast(substr("date",1,4) AS bigint) = 2020
   ```
**참고**  
INSERT INTO 문은 대상 테이블에 최대 100개의 파티션 쓰기를 지원합니다. 또한 100개 이상의 파티션을 추가하려면 여러 INSERT INTO 문을 실행합니다. 자세한 내용은 [CTAS 및 INSERT INTO를 사용하여 100개 파티션 한도 문제 해결](ctas-insert-into.md) 단원을 참조하세요.

## 4단계: 성능 및 비용 차이 측정
<a name="ctas-insert-into-etl-step-4-measure-performance-and-cost-differences"></a>

데이터를 변환한 후에는 새 테이블 및 이전 테이블에서 동일한 쿼리를 실행하고 결과를 비교하여 성능 향상 및 비용 절감을 측정할 수 있습니다.

**참고**  
Athena 쿼리별 비용에 대한 자세한 내용은 [Amazon Athena 요금](https://aws.amazon.com/athena/pricing)을 참조하세요.

**성능 향상 및 비용 차이를 측정하려면**

1. 원본 테이블에서 다음 쿼리를 실행합니다. 쿼리는 연도의 모든 값에 대해 고유 ID 수를 찾습니다.

   ```
   SELECT substr("date",1,4) as year,
          COUNT(DISTINCT id)
   FROM original_csv
   GROUP BY 1 ORDER BY 1 DESC
   ```

1. 쿼리가 실행된 시간과 스캔 데이터의 양을 적어둡니다.

1. 새 테이블에서 동일한 쿼리를 실행하고 쿼리 런타임 및 스캔 데이터의 양을 적어둡니다.

   ```
   SELECT year,
     COUNT(DISTINCT id)
   FROM new_parquet
   GROUP BY 1 ORDER BY 1 DESC
   ```

1. 결과를 비교하고 성능 및 비용 차이를 계산합니다. 다음 샘플 결과는 새 테이블의 테스트 쿼리가 이전 테이블의 쿼리보다 빠르고 저렴하다는 것을 보여줍니다.  
****    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/athena/latest/ug/ctas-insert-into-etl.html)

1. 원본 테이블에서 다음 샘플 쿼리를 실행합니다. 이 쿼리에서는 2018년 지구의 평균 최고 기온(섭씨), 평균 최저 기온(섭씨) 및 평균 강우량(mm)을 계산합니다.

   ```
   SELECT element, round(avg(CAST(datavalue AS real)/10),2) AS value
   FROM original_csv
   WHERE element IN ('TMIN', 'TMAX', 'PRCP') AND substr("date",1,4) = '2018'
   GROUP BY 1
   ```

1. 쿼리가 실행된 시간과 스캔 데이터의 양을 적어둡니다.

1. 새 테이블에서 동일한 쿼리를 실행하고 쿼리 런타임 및 스캔 데이터의 양을 적어둡니다.

   ```
   SELECT element, round(avg(CAST(datavalue AS real)/10),2) AS value
   FROM new_parquet
   WHERE element IN ('TMIN', 'TMAX', 'PRCP') and year = '2018'
   GROUP BY 1
   ```

1. 결과를 비교하고 성능 및 비용 차이를 계산합니다. 다음 샘플 결과는 새 테이블의 테스트 쿼리가 이전 테이블의 쿼리보다 빠르고 저렴하다는 것을 보여줍니다.  
****    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/athena/latest/ug/ctas-insert-into-etl.html)

## 요약
<a name="ctas-insert-into-etl-summary"></a>

이 주제에서는 Athena에 CTAS 및 INSERT INTO 문을 사용하여 ETL 작업을 수행하는 방법을 알아보았습니다. CTAS 문을 사용하여 데이터를 Snappy 압축을 사용하는 Parquet 형식으로 변환하는 첫 번째 변환 세트를 수행했습니다. 또한 CTAS 문을 사용하여 분할되지 않은 데이터 세트에서 분할된 데이터 세트로 변환했습니다. 이를 통해 데이터 세트의 크기를 줄이고 쿼리 실행 비용을 낮출 수 있었습니다. 새 데이터를 사용할 수 있게 되면 CTAS 문을 통해 생성한 테이블에 데이터를 변환하고 로드하는 데 INSERT INTO 문을 사용할 수 있습니다.

# CTAS 및 INSERT INTO를 사용하여 100개 파티션 한도 문제 해결
<a name="ctas-insert-into"></a>

Athena는 `CREATE TABLE AS SELECT`([CTAS](ctas.md)) 쿼리당 파티션을 100개로 제한합니다. 마찬가지로, [INSERT INTO](https://docs.aws.amazon.com/athena/latest/ug/insert-into.html) 문을 통해 대상 테이블에 최대 100개의 파티션을 추가할 수 있습니다.

이 제한을 초과하면 “HIVE\$1TOO\$1MANY\$1OPEN\$1파티션: 파티션/버킷에 대해 열린 작성자 100개를 초과했습니다.”라는 오류 메시지가 표시될 수 있습니다. 이러한 제한은 CTAS 문(최대 100개의 파티션 생성) 및 일련의 `INSERT INTO` 문(각각 최대 100개의 파티션 삽입)을 사용하여 해결할 수 있습니다.

이 주제의 예제에서는 Amazon S3 버킷 위치 s3://amzn-s3-demo-bucket/에 데이터가 상주하는 `tpch100`이라는 데이터베이스를 사용합니다.

**CTAS 및 INSERT INTO를 사용하여 100개 이상의 파티션이 있는 테이블을 생성하려면**

1. `CREATE EXTERNAL TABLE` 문을 사용하여 원하는 필드에 분할된 테이블을 생성합니다.

   다음 예제 문은 `l_shipdate` 열을 기준으로 데이터를 분할합니다. 테이블에는 2525개의 파티션이 있습니다.

   ```
   CREATE EXTERNAL TABLE `tpch100.lineitem_parq_partitioned`(
     `l_orderkey` int, 
     `l_partkey` int, 
     `l_suppkey` int, 
     `l_linenumber` int, 
     `l_quantity` double, 
     `l_extendedprice` double, 
     `l_discount` double, 
     `l_tax` double, 
     `l_returnflag` string, 
     `l_linestatus` string, 
     `l_commitdate` string, 
     `l_receiptdate` string, 
     `l_shipinstruct` string, 
     `l_comment` string)
   PARTITIONED BY ( 
     `l_shipdate` string)
   ROW FORMAT SERDE 
     'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' STORED AS INPUTFORMAT 
     'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat' OUTPUTFORMAT 
     'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat' LOCATION   's3://amzn-s3-demo-bucket/lineitem/'
   ```

1. 다음과 유사한 `SHOW PARTITIONS <table_name>` 명령을 실행하여 파티션을 나열합니다.

   ```
   SHOW PARTITIONS lineitem_parq_partitioned
   ```

   다음은 샘플 결과의 일부입니다.

   ```
   /*
   l_shipdate=1992-01-02
   l_shipdate=1992-01-03
   l_shipdate=1992-01-04
   l_shipdate=1992-01-05
   l_shipdate=1992-01-06
   
   ...
   
   l_shipdate=1998-11-24
   l_shipdate=1998-11-25
   l_shipdate=1998-11-26
   l_shipdate=1998-11-27
   l_shipdate=1998-11-28
   l_shipdate=1998-11-29
   l_shipdate=1998-11-30
   l_shipdate=1998-12-01
   */
   ```

1. CTAS 쿼리를 실행하여 분할된 테이블을 생성합니다.

   다음 예제에서는 `my_lineitem_parq_partitioned`라는 테이블을 만들고 `WHERE ` 절을 사용하여 `DATE`를 `1992-02-01` 이전으로 제한합니다. 샘플 데이터 세트는 1992년 1월로 시작하므로 1992년 1월에 대한 파티션만 생성됩니다.

   ```
   CREATE table my_lineitem_parq_partitioned
   WITH (partitioned_by = ARRAY['l_shipdate']) AS
   SELECT l_orderkey,
            l_partkey,
            l_suppkey,
            l_linenumber,
            l_quantity,
            l_extendedprice,
            l_discount,
            l_tax,
            l_returnflag,
            l_linestatus,
            l_commitdate,
            l_receiptdate,
            l_shipinstruct,
            l_comment,
            l_shipdate
   FROM tpch100.lineitem_parq_partitioned
   WHERE cast(l_shipdate as timestamp) < DATE ('1992-02-01');
   ```

1. `SHOW PARTITIONS` 명령을 실행하여 원하는 파티션이 테이블에 포함되어 있는지 확인합니다.

   ```
   SHOW PARTITIONS my_lineitem_parq_partitioned;
   ```

   이 예제의 파티션은 1992년 1월부터입니다.

   ```
   /*
   l_shipdate=1992-01-02
   l_shipdate=1992-01-03
   l_shipdate=1992-01-04
   l_shipdate=1992-01-05
   l_shipdate=1992-01-06
   l_shipdate=1992-01-07
   l_shipdate=1992-01-08
   l_shipdate=1992-01-09
   l_shipdate=1992-01-10
   l_shipdate=1992-01-11
   l_shipdate=1992-01-12
   l_shipdate=1992-01-13
   l_shipdate=1992-01-14
   l_shipdate=1992-01-15
   l_shipdate=1992-01-16
   l_shipdate=1992-01-17
   l_shipdate=1992-01-18
   l_shipdate=1992-01-19
   l_shipdate=1992-01-20
   l_shipdate=1992-01-21
   l_shipdate=1992-01-22
   l_shipdate=1992-01-23
   l_shipdate=1992-01-24
   l_shipdate=1992-01-25
   l_shipdate=1992-01-26
   l_shipdate=1992-01-27
   l_shipdate=1992-01-28
   l_shipdate=1992-01-29
   l_shipdate=1992-01-30
   l_shipdate=1992-01-31
   */
   ```

1. `INSERT INTO` 문을 사용하여 테이블에 파티션을 추가합니다.

   다음 예제에서는 1992년 2월의 날짜에 대한 파티션을 추가합니다.

   ```
   INSERT INTO my_lineitem_parq_partitioned
   SELECT l_orderkey,
            l_partkey,
            l_suppkey,
            l_linenumber,
            l_quantity,
            l_extendedprice,
            l_discount,
            l_tax,
            l_returnflag,
            l_linestatus,
            l_commitdate,
            l_receiptdate,
            l_shipinstruct,
            l_comment,
            l_shipdate
   FROM tpch100.lineitem_parq_partitioned
   WHERE cast(l_shipdate as timestamp) >= DATE ('1992-02-01')
   AND cast(l_shipdate as timestamp) < DATE ('1992-03-01');
   ```

1. `SHOW PARTITIONS`를 다시 실행합니다.

   ```
   SHOW PARTITIONS my_lineitem_parq_partitioned;
   ```

   이제 샘플 테이블에는 1992년 1월 및 2월의 파티션이 있습니다.

   ```
   /*
   l_shipdate=1992-01-02
   l_shipdate=1992-01-03
   l_shipdate=1992-01-04
   l_shipdate=1992-01-05
   l_shipdate=1992-01-06
   
   ...
   
   l_shipdate=1992-02-20
   l_shipdate=1992-02-21
   l_shipdate=1992-02-22
   l_shipdate=1992-02-23
   l_shipdate=1992-02-24
   l_shipdate=1992-02-25
   l_shipdate=1992-02-26
   l_shipdate=1992-02-27
   l_shipdate=1992-02-28
   l_shipdate=1992-02-29
   */
   ```

1. 각 파티션에 100개 이하의 파티션을 읽고 추가하는 `INSERT INTO` 문을 계속 사용합니다. 필요한 파티션 수에 도달할 때까지 계속합니다.
**중요**  
`WHERE` 조건을 설정할 때 쿼리가 중첩되지 않도록 해야 합니다. 그렇지 않으면 일부 파티션에 중복된 데이터가 있을 수 있습니다.