CREATE TABLE AS
CREATE TABLE AS
쿼리 결과를 그대로 테이블로 만들어 두고 싶을 때가 있어요. 분석 결과를 저장해 두거나, 무거운 조회를 한 번만 실행해 스냅샷처럼 보관하고 싶을 때 말이죠. CREATE TABLE AS는 그런 요구에 딱 맞는 명령이에요. SELECT 명령이 계산한 데이터로 테이블을 만들고 채워 줘요.
이 명령은 뷰를 만드는 것과 겉보기엔 비슷하지만 실제로는 꽤 달라요. 새 테이블을 만들고 쿼리를 딱 한 번 평가해서 초기 데이터를 채워 넣을 뿐, 이후에 쿼리의 원본 테이블이 바뀌어도 새 테이블은 그 변경을 따라가지 않아요. 반면 뷰는 조회될 때마다 정의한 SELECT 문을 다시 평가하죠. 한 번의 결과만 필요한 순간에는 CREATE TABLE AS가 더 어울려요.
테이블에 사용되는 스키마에 대한 CREATE 권한이 필요해요.
출처: PostgreSQL 문서
본문
Synopsis
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name
[ (column_name [, ...] ) ]
[ USING method ]
[ WITH ( storage_parameter [= value] [, ... ] ) | WITHOUT OIDS ]
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
[ TABLESPACE tablespace_name ]
AS query
[ WITH [ NO ] DATA ]
Description
CREATE TABLE AS는 SELECT 명령이 계산한 데이터로 테이블을 만들어요. 테이블 컬럼은 SELECT의 출력 컬럼과 연결된 이름·데이터 타입을 가져요(새 컬럼 이름 목록을 명시적으로 주면 컬럼 이름을 덮어쓸 수 있어요).
CREATE TABLE AS는 뷰를 만드는 것과 다소 비슷하지만 실제로는 꽤 달라요. 새 테이블을 만들고 쿼리를 단 한 번 평가해서 초기 데이터를 채워 넣어요. 새 테이블은 이후 쿼리의 원본 테이블이 바뀌는 것을 추적하지 않아요. 반면 뷰는 조회될 때마다 정의한 SELECT 문을 재평가해요.
CREATE TABLE AS는 테이블에 사용되는 스키마에 대한 CREATE 권한이 필요해요.
Parameters
GLOBAL 또는 LOCAL
호환성을 위해 무시돼요. 이 키워드의 사용은 더 이상 권장하지 않아요. 자세한 내용은 CREATE TABLE을 참고하세요.
TEMPORARY 또는 TEMP
지정하면 테이블이 임시 테이블로 만들어져요. 자세한 내용은 CREATE TABLE을 참고하세요.
UNLOGGED
지정하면 테이블이 unlogged 테이블로 만들어져요. 자세한 내용은 CREATE TABLE을 참고하세요.
IF NOT EXISTS
같은 이름의 릴레이션이 이미 있어도 오류를 내지 않아요. 그저 통지를 내고 테이블을 수정하지 않은 채 둬요.
table_name
만들 테이블의 이름(스키마 한정 가능)이에요.
column_name
새 테이블의 컬럼 이름이에요. 컬럼 이름을 주지 않으면 쿼리의 출력 컬럼 이름에서 가져와요.
USING method
이 선택 절은 새 테이블의 내용을 저장하는 데 사용할 테이블 접근 방식을 지정해요. 그 방식은 TABLE 타입의 접근 방식이어야 해요. 자세한 내용은 62장을 참고하세요. 이 옵션을 지정하지 않으면 새 테이블에 기본 테이블 접근 방식이 선택돼요. default_table_access_method를 참고하세요.
WITH ( storage_parameter [= value] [, ... ] )
이 절은 새 테이블의 선택적 저장 매개변수를 지정해요. 자세한 내용은 CREATE TABLE 문서의 Storage Parameters를 참고하세요. 역호환성을 위해 테이블의 WITH 절은 OIDS=FALSE도 포함할 수 있는데, 새 테이블의 행이 OID(객체 식별자)를 포함하지 않도록 지정해요. OIDS=TRUE는 더 이상 지원되지 않아요.
WITHOUT OIDS
이것은 테이블을 WITHOUT OIDS로 선언하는 역호환 문법이에요. WITH OIDS로 테이블을 만드는 것은 더 이상 지원되지 않아요.
ON COMMIT
임시 테이블이 트랜잭션 블록 끝에서 어떻게 동작할지는 ON COMMIT으로 제어해요. 세 가지 옵션이 있어요.
PRESERVE ROWS
트랜잭션이 끝날 때 특별한 작업을 하지 않아요. 기본 동작이에요.
DELETE ROWS
각 트랜잭션 블록이 끝날 때 임시 테이블의 모든 행이 삭제돼요. 본질적으로 각 커밋에서 자동 TRUNCATE가 일어나요.
DROP
임시 테이블이 현재 트랜잭션 블록이 끝날 때 삭제돼요.
TABLESPACE tablespace_name
tablespace_name은 새 테이블을 만들 테이블스페이스의 이름이에요. 지정하지 않으면 default_tablespace를 참고하고, 테이블이 임시면 temp_tablespaces를 참고해요.
query
SELECT, TABLE, VALUES 명령이거나, 준비된 SELECT, TABLE, VALUES 쿼리를 실행하는 EXECUTE 명령이에요.
WITH [ NO ] DATA
이 절은 쿼리가 만든 데이터를 새 테이블에 복사할지 여부를 지정해요. 복사하지 않으면 테이블 구조만 복사돼요. 기본값은 데이터를 복사하는 거예요.
Notes
이 명령은 기능적으로 SELECT INTO와 비슷하지만, SELECT INTO 문법의 다른 용도와 헷갈릴 가능성이 낮아 선호돼요. 게다가 CREATE TABLE AS는 SELECT INTO가 제공하는 기능의 상위 집합을 제공해요.
Examples
테이블 films의 최근 항목만으로 구성된 새 테이블 films_recent를 만들어 볼게요.
CREATE TABLE films_recent AS
SELECT * FROM films WHERE date_prod >= '2002-01-01';
테이블을 완전히 복사하려면 TABLE 명령을 쓰는 짧은 형태를 쓸 수도 있어요.
CREATE TABLE films2 AS
TABLE films;
준비된 문을 사용해 테이블 films의 최근 항목만으로 구성된 새 임시 테이블 films_recent를 만들어 볼게요. 새 테이블은 커밋 때 삭제돼요.
PREPARE recentfilms(date) AS
SELECT * FROM films WHERE date_prod > $1;
CREATE TEMP TABLE films_recent ON COMMIT DROP AS
EXECUTE recentfilms('2002-01-01');
Compatibility
CREATE TABLE AS는 SQL 표준을 따르는 편이에요. 다음은 비표준 확장 기능이에요.
- 표준은 서브쿼리 절 주변에 괄호를 요구하지만, PostgreSQL에서는 이 괄호가 선택 사항이에요.
- 표준에서는
WITH [ NO ] DATA절이 필수이지만, PostgreSQL에서는 선택 사항이에요. - PostgreSQL은 임시 테이블을 표준과 꽤 다르게 처리해요. 자세한 내용은 CREATE TABLE을 참고하세요.
WITH절은 PostgreSQL 확장이고, 저장 매개변수는 표준에 없어요.- PostgreSQL의 테이블스페이스 개념은 표준의 일부가 아니에요. 따라서
TABLESPACE절은 확장 기능이에요.
더 알아보기 (Learn more)
CREATE TABLE— 새 테이블을 만드는 가장 기본적인 명령이에요.SELECT INTO—CREATE TABLE AS와 기능적으로 비슷한 옛 방식이에요.SELECT— 테이블을 채울 쿼리를 작성할 때 써요.ALTER TABLE— 만들어진 테이블의 구조를 바꿀 때 써요.