CREATE VIEW
CREATE VIEW
CREATE VIEW 명령은 하나 이상의 기존 테이블(또는 다른 유효한 쿼리 표현식)에 대한 쿼리를 기반으로 현재/지정된 스키마에 새 뷰(view)를 만드는 명령이에요.
출처: CREATE VIEW
본문
하나 이상의 기존 테이블(또는 다른 유효한 쿼리 표현식)에 대한 쿼리를 기반으로 현재/지정된 스키마에 새 뷰를 만드는 명령입니다. 이 명령은 다음 변형을 지원해요: ALTER VIEW, DROP VIEW, SHOW VIEWS, DESCRIBE VIEW
Syntax
CREATE [ OR REPLACE ] [ SECURE ] [ { [ { LOCAL | GLOBAL } ] TEMP | TEMPORARY | VOLATILE } ] [ RECURSIVE ] VIEW [ IF NOT EXISTS ] <name>
[ ( <column_list> ) ]
[ <col1> [ WITH ] MASKING POLICY <policy_name> [ USING ( <col1> , <cond_col1> , ... ) ]
[ WITH ] PROJECTION POLICY <policy_name>
[ WITH ] TAG ( <tag_name> = '<tag_value>' [ , <tag_name> = '<tag_value>' , ... ] ) ]
[ , <col2> [ ... ] ]
[ [ WITH ] ROW ACCESS POLICY <policy_name> ON ( <col_name> [ , <col_name> ... ] ) ]
[ [ WITH ] TAG ( <tag_name> = '<tag_value>' [ , <tag_name> = '<tag_value>' , ... ] ) ]
[ CHANGE_TRACKING = { TRUE | FALSE } ]
[ COPY GRANTS ]
[ COPY TAGS ]
[ COMMENT = '<string_literal>' ]
[ [ WITH ] ROW ACCESS POLICY <policy_name> ON ( <col_name> [ , <col_name> ... ] ) ]
[ [ WITH ] AGGREGATION POLICY <policy_name> [ ENTITY KEY ( <col_name> [ , <col_name> ... ] ) ] ]
[ [ WITH ] JOIN POLICY <policy_name> [ ALLOWED JOIN KEYS ( <col_name> [ , ... ] ) ] ]
[ [ WITH ] TAG ( <tag_name> = '<tag_value>' [ , <tag_name> = '<tag_value>' , ... ] ) ]
[ WITH CONTACT ( <purpose> = <contact_name> [ , <purpose> = <contact_name> ... ] ) ]
AS <select_statement>
Variant syntax
CREATE OR ALTER VIEW
이미 존재하지 않으면 새 뷰를 만들고, 존재하면 기존 뷰의 속성을 문에 정의된 것과 일치하도록 업데이트해요. CREATE OR ALTER VIEW 문은 CREATE VIEW 문의 구문 규칙을 따르며 ALTER VIEW 문과 동일한 제한 사항을 가집니다.
CREATE OR ALTER [ SECURE ] [ { [ { LOCAL | GLOBAL } ] TEMP | TEMPORARY | VOLATILE } ] [ RECURSIVE ] VIEW <name>
[ ( <column_list> ) ]
[ CHANGE_TRACKING = { TRUE | FALSE } ]
[ COMMENT = '<string_literal>' ]
AS <select_statement>
Required parameters (필수 파라미터)
name— 뷰의 식별자를 지정해요. 뷰가 생성되는 스키마 내에서 고유해야 합니다. 또한 식별자는 알파벳 문자로 시작해야 하고, 전체 식별자 문자열을 큰따옴표로 감싸지 않는 한 공백이나 특수 문자를 포함할 수 없어요 (예:"My object"). 큰따옴표로 감싼 식별자는 대소문자를 구분합니다. 자세한 내용은 Identifier requirements 문서를 참고하세요.<select_statement>— 뷰를 만드는 데 사용되는 쿼리를 지정해요. 하나 이상의 소스 테이블이나 다른 유효한SELECT문일 수 있습니다. 이 쿼리는 뷰의 텍스트/정의 역할을 하며SHOW VIEWS출력과VIEWSInformation Schema 뷰에 표시됩니다.
Optional parameters (선택 파라미터)
SECURE— 뷰가 보안(secure)임을 지정해요. 보안 뷰에 대한 자세한 내용은 Working with Secure Views 문서를 참고하세요. 기본값: 값 없음(뷰는 보안 아님)TEMP | TEMPORARY | VOLATILE— 뷰가 생성된 세션 동안만 지속됨을 지정해요. 임시 뷰와 그 모든 내용은 세션이 끝나면 삭제됩니다.GLOBAL TEMPORARY같은 동의어와 약칭은 다른 데이터베이스와의 호환성(예:CREATE VIEW문 마이그레이션 시 오류 방지)을 위해 제공됩니다. 기본값: 값 없음 —TEMPORARY로 선언되지 않으면 뷰는 영구적입니다. 스키마에 이미 존재하는 뷰와 같은 이름의 임시 뷰를 만들면 임시 뷰를 삭제할 때까지 해당 세션의 모든 쿼리·작업이 임시 뷰에만 영향을 줍니다. 임시 뷰를 삭제하면 스키마에 이미 존재하는 뷰가 아니라 임시 뷰가 삭제됩니다.RECURSIVE— 뷰가 반드시 CTE(공통 테이블 표현식)를 사용하지 않고도 재귀 구문으로 자기 자신을 참조할 수 있음을 지정해요. 재귀 뷰와RECURSIVE키워드에 대한 자세한 내용은 Recursive Views를 참고하세요. 기본값: 값 없음(뷰는 재귀가 아니거나 CTE로만 재귀)( <column_list> )— 새 뷰의 컬럼 이름을 바꾸거나 컬럼에 주석을 추가하려면 컬럼 이름과 (필요한 경우) 컬럼 주석을 지정하는 컬럼 목록을 포함해요. (컬럼 데이터 유형을 지정할 필요는 없어요.) 뷰의 컬럼 중 표현식(단순 컬럼 이름이 아닌)에 기반한 것이 있다면 각 컬럼에 컬럼 이름을 제공해야 합니다. 예:
각 컬럼에 선택적 주석을 지정할 수 있어요. 예:CREATE VIEW v1 (pre_tax_profit, taxes, after_tax_profit) AS SELECT revenue - cost, (revenue - cost) * tax_rate, (revenue - cost) * (1.0 - tax_rate) FROM table1;
주석은 컬럼 이름이 모호할 때 특히 유용해요. 주석을 보려면CREATE VIEW v1 (pre_tax_profit COMMENT 'revenue minus cost', taxes COMMENT 'assumes taxes are a fixed percentage of profit', after_tax_profit) AS SELECT revenue - cost, (revenue - cost) * tax_rate, (revenue - cost) * (1.0 - tax_rate) FROM table1;DESCRIBE VIEW를 사용하세요.MASKING POLICY <policy_name>— 컬럼에 설정할 마스킹 정책을 지정해요.USING ( <col1> , <cond_col1> , ... )— 조건부 마스킹 정책 SQL 표현식에 전달할 인자를 지정해요. 목록의 첫 번째 컬럼은 정책 조건이 데이터를 마스킹하거나 토큰화할 컬럼을 지정하며, 마스킹 정책이 설정된 컬럼과 일치해야 해요. 추가 컬럼은 첫 번째 컬럼에 대해 쿼리할 때 쿼리 결과의 각 행에서 데이터를 마스킹·토큰화할지 결정하기 위해 평가할 컬럼을 지정합니다.USING절을 생략하면 Snowflake는 조건부 마스킹 정책을 일반 마스킹 정책으로 취급해요.PROJECTION POLICY <policy_name>— 컬럼에 설정할 프로젝션 정책을 지정해요.CHANGE_TRACKING = { TRUE | FALSE }— 뷰에서 변경 추적을 활성화할지 지정해요.COPY GRANTS—OR REPLACE절로 새 뷰를 만들 때 원래 뷰의 접근 권한을 유지해요.OWNERSHIP을 제외한 모든 권한을 기존 뷰에서 새 뷰로 복사합니다. 새 뷰는 스키마에서 객체 유형에 대해 정의된 미래 권한(future grants)은 상속하지 않아요. 기본적으로CREATE VIEW문을 실행하는 역할이 새 뷰를 소유합니다. 권한 복사 작업은CREATE VIEW문과 함께(같은 트랜잭션 안에서) 원자적으로 발생합니다. 기본값: 값 없음(권한이 복사되지 않음)COPY TAGS—CREATE OR REPLACE VIEW를 사용할 때 태그를 적용해요.WITH TAG절 없이CREATE OR REPLACE VIEW … COPY TAGS를 사용하면 교체된 뷰와 그 컬럼의 태그가 새 뷰에 유지됩니다.WITH TAG절과COPY TAGS를 함께 사용하면 Snowflake는 적용 가능한 소스의 태그를 결합합니다. 두 소스가 같은 태그를 설정하면 교체된 뷰(COPY TAGS로 넘어온)의 값이 우선합니다.COMMENT = '<string_literal>'— 뷰에 대한 주석을 지정해요. 기본값: 값 없음ROW ACCESS POLICY <policy_name> ON ( <col_name> [ , ... ] )— 뷰에 설정할 행 접근 정책을 지정해요.AGGREGATION POLICY <policy_name> [ ENTITY KEY ( <col_name> [ , ... ] ) ]— 뷰에 설정할 집계 정책을 지정해요. 선택적ENTITY KEY파라미터로 뷰 내 개체(entity)를 고유하게 식별하는 컬럼을 정의합니다. 자세한 내용은 Implementing entity-level privacy with aggregation policies 문서를 참고하세요.JOIN POLICY <policy_name> [ ALLOWED JOIN KEYS ( <col_name> [ , ... ] ) ]— 뷰에 설정할 조인 정책을 지정해요. 선택적ALLOWED JOIN KEYS파라미터로 이 정책이 적용되는 동안 조인 컬럼으로 사용이 허용되는 컬럼을 정의합니다. 자세한 내용은 Join policies 문서를 참고하세요. 이 파라미터는CREATE OR ALTER변형 구문에서 지원되지 않아요.WITH DATA METRIC FUNCTION— 생성 시 뷰에 하나 이상의 데이터 메트릭 함수(DMF)를 연결해요. DMF는 생성되자마자 뷰에 구성된 스케줄로 실행을 시작합니다. 여러 DMF 바인딩을 쉼표로 구분해 연결할 수 있으며, 각 바인딩은EXECUTE AS ROLE,ANOMALY_DETECTION,SENSITIVITY,DATA_QUALITY_NOTIFICATION,EXPECTATION을 포함한 Data metric function actions과 같은 속성을 받아요. Snowflake는 괄호 없이 바인딩 목록을 받는 형식도 허용하지만, 그 형식은 더 이상 사용되지 않습니다. 기본값: 값 없음(뷰에 연결된 DMF 없음)TAG ( ... )— 태그 이름과 태그 문자열 값을 지정해요. 태그 값은 항상 문자열이며 최대 문자 수는 256이에요.WITH CONTACT ( <purpose> = <contact_name> [ , ... ] )— 새 객체를 하나 이상의 연락처와 연결해요.AS절(이 명령에서 지원되는 경우)을 제외한 다른 모든 절 뒤에WITH CONTACT절을 지정하세요.
Access control requirements (접근 제어 요구 사항)
이 작업을 실행하는 데 사용되는 역할은 최소한 다음 권한을 보유해야 해요. 뷰를 만들 때 마스킹 정책, 행 접근 정책, 객체 태그, 또는 이들의 조합을 적용할 때만 필요합니다. OWNERSHIP은 객체에 대한 특별한 권한으로, 객체를 생성한 역할에 자동으로 부여되지만 소유 역할(또는 MANAGE GRANTS 권한이 있는 역할)이 GRANT OWNERSHIP 명령으로 다른 역할에 이전할 수 있습니다.
참고 관리형 접근 스키마에서 스키마 소유자(즉 스키마에
OWNERSHIP권한을 가진 역할) 또는MANAGE GRANTS권한을 가진 역할만 미래 권한을 포함한 스키마 내 객체의 권한을 부여·취소할 수 있어요.
스키마의 객체를 조작하려면 상위 데이터베이스에 대한 권한과 상위 스키마에 대한 권한이 각각 최소 하나씩 필요합니다. 지정된 권한 집합으로 사용자 정의 역할을 만드는 방법은 Creating custom roles 문서를, 보안 객체에 대한 SQL 작업의 역할·권한 부여에 대한 일반적인 정보는 Overview of Access Control 문서를 참고하세요.
General usage notes (일반 사용 참고 사항)
이런 시나리오에서는 뷰를 쿼리하면 컬럼 관련 오류가 반환됩니다.
Examples (예제)
Basic examples
현재 스키마에, 주석이 있고 테이블의 모든 행을 선택하는 뷰를 만들어 봅시다.
CREATE VIEW myview COMMENT='Test view' AS SELECT col1, col2 FROM mytable;
SHOW VIEWS;
+---------------------------------+-------------------+----------+---------------+-------------+----------+-----------+--------------------------------------------------------------------------+
| created_on | name | reserved | database_name | schema_name | owner | comment | text |
|---------------------------------+-------------------+----------+---------------+-------------+----------+-----------+--------------------------------------------------------------------------|
| Thu, 19 Jan 2017 15:00:37 -0800 | MYVIEW | | MYTEST1 | PUBLIC | SYSADMIN | Test view | CREATE VIEW myview COMMENT='Test view' AS SELECT col1, col2 FROM mytable |
+---------------------------------+-------------------+----------+---------------+-------------+----------+-----------+--------------------------------------------------------------------------+
다음 예제는 보안 뷰라는 점만 제외하면 이전 예제와 같아요.
CREATE OR REPLACE SECURE VIEW myview COMMENT='Test secure view' AS SELECT col1, col2 FROM mytable;
SELECT is_secure FROM information_schema.views WHERE table_name = 'MYVIEW';
다음은 재귀 뷰를 만드는 두 가지 방법을 보여줘요.
먼저 테이블을 만들고 로드해 봅시다.
CREATE OR REPLACE TABLE employees (title VARCHAR, employee_ID INTEGER, manager_ID INTEGER);
INSERT INTO employees (title, employee_ID, manager_ID) VALUES
('President', 1, NULL), -- The President has no manager.
('Vice President Engineering', 10, 1),
('Programmer', 100, 10),
('QA Engineer', 101, 10),
('Vice President HR', 20, 1),
('Health Insurance Analyst', 200, 20);
재귀 CTE를 사용하는 뷰를 만든 다음 뷰를 쿼리해 봅시다.
CREATE VIEW employee_hierarchy (title, employee_ID, manager_ID, "MGR_EMP_ID (SHOULD BE SAME)", "MGR TITLE") AS (
WITH RECURSIVE employee_hierarchy_cte (title, employee_ID, manager_ID, "MGR_EMP_ID (SHOULD BE SAME)", "MGR TITLE") AS (
-- Start at the top of the hierarchy ...
SELECT title, employee_ID, manager_ID, NULL AS "MGR_EMP_ID (SHOULD BE SAME)", 'President' AS "MGR TITLE"
FROM employees
WHERE title = 'President'
UNION ALL
-- ... and work our way down one level at a time.
SELECT employees.title,
employees.employee_ID,
employees.manager_ID,
employee_hierarchy_cte.employee_id AS "MGR_EMP_ID (SHOULD BE SAME)",
employee_hierarchy_cte.title AS "MGR TITLE"
FROM employees INNER JOIN employee_hierarchy_cte
WHERE employee_hierarchy_cte.employee_ID = employees.manager_ID
)
SELECT *
FROM employee_hierarchy_cte
);
SELECT *
FROM employee_hierarchy
ORDER BY employee_ID;
+----------------------------+-------------+------------+-----------------------------+----------------------------+
| TITLE | EMPLOYEE_ID | MANAGER_ID | MGR_EMP_ID (SHOULD BE SAME) | MGR TITLE |
|----------------------------+-------------+------------+-----------------------------+----------------------------|
| President | 1 | NULL | NULL | President |
| Vice President Engineering | 10 | 1 | 1 | President |
| Vice President HR | 20 | 1 | 1 | President |
| Programmer | 100 | 10 | 10 | Vice President Engineering |
| QA Engineer | 101 | 10 | 10 | Vice President Engineering |
| Health Insurance Analyst | 200 | 20 | 20 | Vice President HR |
+----------------------------+-------------+------------+-----------------------------+----------------------------+
RECURSIVE 키워드를 사용하는 뷰를 만든 다음 쿼리해 봅시다.
CREATE RECURSIVE VIEW employee_hierarchy_02 (title, employee_ID, manager_ID, "MGR_EMP_ID (SHOULD BE SAME)", "MGR TITLE") AS (
-- Start at the top of the hierarchy ...
SELECT title, employee_ID, manager_ID, NULL AS "MGR_EMP_ID (SHOULD BE SAME)", 'President' AS "MGR TITLE"
FROM employees
WHERE title = 'President'
UNION ALL
-- ... and work our way down one level at a time.
SELECT employees.title,
employees.employee_ID,
employees.manager_ID,
employee_hierarchy_02.employee_id AS "MGR_EMP_ID (SHOULD BE SAME)",
employee_hierarchy_02.title AS "MGR TITLE"
FROM employees INNER JOIN employee_hierarchy_02
WHERE employee_hierarchy_02.employee_ID = employees.manager_ID
);
SELECT *
FROM employee_hierarchy_02
ORDER BY employee_ID;
+----------------------------+-------------+------------+-----------------------------+----------------------------+
| TITLE | EMPLOYEE_ID | MANAGER_ID | MGR_EMP_ID (SHOULD BE SAME) | MGR TITLE |
|----------------------------+-------------+------------+-----------------------------+----------------------------|
| President | 1 | NULL | NULL | President |
| Vice President Engineering | 10 | 1 | 1 | President |
| Vice President HR | 20 | 1 | 1 | President |
| Programmer | 100 | 10 | 10 | Vice President Engineering |
| QA Engineer | 101 | 10 | 10 | Vice President Engineering |
| Health Insurance Analyst | 200 | 20 | 20 | Vice President HR |
+----------------------------+-------------+------------+-----------------------------+----------------------------+
Data metric function examples
컬럼의 빈 값을 세는 DMF가 있는 뷰를 만들어 봅시다. 뷰의 경우 WITH DATA METRIC FUNCTION 절이 AS SELECT 정의 앞에 와야 해요.
CREATE OR REPLACE VIEW active_customers
WITH DATA METRIC FUNCTION (
SNOWFLAKE.CORE.BLANK_COUNT
ON (email)
EXPECTATION no_blank_emails ( VALUE = 0 )
)
AS SELECT customer_id, email FROM customers WHERE status = 'active';
CREATE OR ALTER VIEW examples
기본 예제: 컬럼이 하나 있는 테이블 my_table을 만들어 봅시다.
CREATE OR ALTER TABLE my_table(a INT);
테이블 my_table에서 컬럼 a를 선택하는 v2라는 뷰를 만들어 봅시다.
CREATE OR ALTER VIEW v2(one)
AS SELECT a FROM my_table;
뷰 v2를 만들거나 변경하면서 뷰의 COMMENT와 CHANGE_TRACKING 속성을 추가·업데이트해 봅시다.
CREATE OR ALTER VIEW v2(one)
COMMENT = 'fff'
CHANGE_TRACKING = true
AS SELECT a FROM my_table;
뷰 v2를 만들거나 변경하면서 컬럼에 주석을 추가해 봅시다.
CREATE OR ALTER VIEW v2(one COMMENT 'bar')
COMMENT = 'foo'
AS SELECT a FROM my_table;
이전에 설정한 속성 해제하기: CREATE OR ALTER VIEW 문에서 이전에 설정한 속성이 없으면 그 속성이 해제됩니다. 다음 예제에서는 이전 예제의 뷰 v2의 COMMENT 속성을 해제합니다.
CREATE OR ALTER VIEW v2(one COMMENT 'bar')
CHANGE_TRACKING = true
AS SELECT a FROM my_table;