CREATE VIEW

1つ以上ある既存のテーブル(またはその他の有効なクエリ式)のクエリに基づいて、現在のスキーマまたは指定されたスキーマに新しいビューを作成します。

こちらもご参照ください。

ALTER VIEWDROP VIEWSHOW VIEWSDESCRIBE VIEW

構文

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 ] 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>' , ... ] ) ]
  [ COPY GRANTS ]
  [ COMMENT = '<string_literal>' ]
  AS <select_statement>
Copy

必須パラメーター

name

ビューの識別子を指定します。ビューが作成されるスキーマに対して一意である必要があります。

また、識別子はアルファベット文字で始まる必要があり、識別子文字列全体が二重引用符で囲まれていない限り、スペースや特殊文字を含めることはできません(例: "My object")。二重引用符で囲まれた識別子も大文字と小文字が区別されます。

詳細については、 識別子の要件 をご参照ください。

select_statement

ビューの作成に使用するクエリを指定します。1つ以上のソーステーブルまたはその他の有効な SELECT ステートメントに配置できます。このクエリは、ビューのテキスト/定義として機能し、 SHOW VIEWS 出力と VIEWS Information Schemaビューに表示されます。

オプションのパラメーター

SECURE

ビューがセキュアであることを指定します。セキュアビューの詳細については、 セキュアビューの使用 をご参照ください。

デフォルト: 値なし(ビューはセキュアではない)

{ [ { LOCAL | GLOBAL } ] TEMP | TEMPORARY | VOLATILE }

ビューを作成した セッション の間だけ永続させることを指定します。仮ビューとそのすべてのコンテンツは、セッションの終了時にドロップされます。

TEMPORARY (例: GLOBAL TEMPORARY)の同義語と略語は、他のデータベースとの互換性のために提供されています(例えば、 CREATE VIEW ステートメントの移行時のエラーを防ぐため)。これらのキーワードのいずれかを使用して作成されたビューは、 TEMPORARY キーワードを使用して作成されたビューと同じように表示され、動作します。

デフォルト:値なし。ビューが TEMPORARY と宣言されていない場合、そのビューは永続的です。

予期しない競合を回避するには、スキーマに既存のビューの名前を仮ビューに付けないようにします。

スキーマ内にある別のビューと同じ名前の仮ビューを作成した場合、そのビューで使用されるすべてのクエリや操作は、仮ビューがドロップされるまで、セッション内の仮ビューにのみ影響します。ビューをドロップする場合は、スキーマに既存のビューではなく、仮ビューをドロップします。

RECURSIVE

ビューが必ずしも CTE (共通テーブル式)を使用することなく再帰構文を使用してそれ自体を参照できることを指定します。一般的な再帰ビュー、および特に RECURSIVE キーワードの詳細については、 再帰的ビュー(非マテリアライズドビューのみ) および以下の再帰ビューの例をご参照ください。

デフォルト: 値なし(ビューは再帰的ではない、または 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;
Copy

列ごとにオプションのコメントを指定できます。例:

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;
Copy

コメントは、列名がわかりにくい場合に特に役立ちます。

コメントを表示するには、 DESCRIBE VIEW を使用します。

MASKING POLICY = policy_name

列に設定する マスキングポリシー を指定します。

USING ( col_name , cond_col_1 ... )

条件付きマスキングポリシー SQL 式に渡す引数を指定します。

リストの最初の列は、データをマスクまたはトークン化するポリシー条件の列を指定し、マスキングポリシーが設定されている列と一致する 必要 があります。

追加の列は、最初の列でクエリが実行されたときに、クエリ結果の各行のデータをマスクするかトークン化するかを決定するために評価する列を指定します。

USING 句が省略されている場合、Snowflakeは条件付きマスキングポリシーを通常の マスキングポリシー として扱います。

COPY GRANTS

OR REPLACE 句を使用して新しいビューが作成されるときに、元のビューのアクセス許可を保持します。

このパラメーターは、既存のビューから新しいビューに OWNERSHIP を 除く すべての権限をコピーします。新しいビューは、スキーマ内のオブジェクト型に定義された将来の付与を継承 しません。デフォルトでは、 CREATE VIEW ステートメントを実行するロールが新しいビューを所有します。

パラメーターが CREATE VIEW ステートメントに含まれていない場合、新しいビューは元のビューに付与された明示的なアクセス権限を継承 しません が、スキーマ内のオブジェクトタイプに定義された将来の権限は継承します。

許可をコピーする操作は、 CREATE VIEW ステートメントで(つまり、同じトランザクション内で)アトミックに発生することに注意してください。

デフォルト:値なし(付与はコピーされない)

COMMENT = 'string_literal'

ビューのコメントを指定します。

デフォルト: 値なし

ROW ACCESS POLICY policy_name ON ( col_name [ , col_name ... ] )

ビューに設定する 行アクセスポリシー を指定します。

TAG ( tag_name = 'tag_value' [ , tag_name = 'tag_value' , ... ] )

タグ の名前とタグ文字列の値を指定します。

タグ値は常に文字列であり、タグ値の最大文字数は256です。

ステートメントにあるタグの指定の詳細については、 オブジェクトおよび列のタグクォータ をご参照ください。

アクセス制御の要件

この SQL コマンドの実行に使用される ロール には、少なくとも次の 権限 が必要です。

権限

オブジェクト

メモ

CREATE VIEW

スキーマ

SELECT

テーブル、外部テーブル、ビュー

ビュー定義でクエリされるすべてのテーブルおよび/またはビューで必要です。

APPLY

マスキングポリシー、行アクセスポリシー、タグ

ビューの作成時に、マスキングポリシー、行アクセスポリシー、オブジェクトタグ、またはこうした ガバナンス 機能の任意の組み合わせを適用する場合にのみ必要です。

OWNERSHIP

ビュー

スキーマに既存のオブジェクトと同じ名前の仮オブジェクトを作成するには、ロールにオブジェクトの権限(OWNERSHIP)を付与するか継承する必要があります。

Note that in a managed access schema, only the schema owner (i.e. the role with the OWNERSHIP privilege on the schema) or a role with the MANAGE GRANTS privilege can grant or revoke privileges on objects in the schema, including future grants.

スキーマ内の任意のオブジェクトを操作するには、親データベースとスキーマに対する USAGE 権限も必要であることに注意してください。

指定された権限のセットを使用してカスタムロールを作成する手順については、 カスタムロールの作成 をご参照ください。

セキュリティ保護可能なオブジェクト に対して SQL アクションを実行するためのロールと権限付与に関する一般的な情報については、 アクセス制御の概要 をご参照ください。

使用上の注意

  • ビュー定義には、 ORDER BY 句(例: create view v1 as select * from t1 ORDER BY column1)を含めることができます。ただし、Snowflakeは、ほとんどのビュー定義から ORDER BY 句を 除外 することをお勧めします。並べ替えの恩恵を受けないコンテキストでビューが使用される場合、 ORDER BY 句は不要なコストを追加します。たとえば、ビューが結合で使用され、結合列が ORDER BY 列と同じでない場合、ビューの結果を並べ替えるための追加コストは通常無駄になります。クエリ結果を並べ替える必要がある場合は、通常、ビュー自体ではなく、ビューを使用するクエリで ORDER BY を指定する方が効率的です。

  • ビュー定義は動的ではありません。特に列がドロップされたときなど、基になるソースがビュー定義と一致しないように変更された場合、ビューは自動的に更新されません。例:

    • ソーステーブルの特定の列を参照するビューが作成され、その後その列はテーブルからドロップされます。

    • ビューはテーブルから SELECT * を使用して作成され、テーブルの列に以下のような変更が加えられます。

      • 列がドロップされます。

      • 列が追加されます。

      • 列の順序が変わります。

    これらのシナリオでは、ビューのクエリは列関連のエラーを返します。

  • ビューのソーステーブルがドロップされた場合、ビューのクエリは object does not exist エラーを返します。

  • スキーマには、同じ名前のテーブルとビューを含めることはできません。同じ名前のテーブルがスキーマに既に存在する場合、 CREATE VIEW ステートメントはエラーを生成します。

  • ビューが作成されると、テーブルおよびその他のデータベースオブジェクトへの 非修飾 参照は、セッションの現在のスキーマではなく、 ビューのスキーマで 解決されます。同様に、部分的に修飾されたオブジェクト(つまり、schema.object)は、セッションの現在のデータベースではなく、ビューのデータベースで解決されます。

    SEARCH_PATH セッションパラメーター(存在する場合)は無視されます。

  • OR REPLACE の使用は、既存のビューで DROP VIEW を使用してから、同じ名前で新しいビューを作成することと同じです。

    CREATE OR REPLACE <オブジェクト> ステートメントはアトミックです。つまり、オブジェクトが置き換えられると、単一のトランザクションで、古いオブジェクトが削除されて新しいオブジェクトが作成されます。

    これは、 CREATE OR REPLACE VIEW 操作と同時に実行されるクエリが、古いビューバージョンまたは新しいビューバージョンのいずれかを使用することを意味します。

    ビューを再作成または交換すると、変更データがドロップされ、ビュー上のストリームが古くなります。 古い ストリームは読み取れません。

  • COPY GRANTS を使用して、

    • データ共有:

      • 既存のセキュアビューが別のアカウントと共有されていた場合は、置換ビューも共有されます。

      • 既存のセキュアビューがデータコンシューマーとしてアカウントと共有され、アクセス権限がアカウント内の他のロールにも付与された場合(親データベースの GRANT IMPORTED PRIVILEGES を使用)、置換ビューにもアクセス権限が付与されます。

    • 置換ビューの SHOW GRANTS 出力には、ステートメントが実行されたときの現在のタイムスタンプとともに、コピーされた権限の被付与者が CREATE VIEW ステートメントを実行したロールとしてリストされます。

  • ビューを作成し、そのビューに対する権限をロールに付与すると、ロールは、ビューがアクセスする基になるテーブルに対して権限がなくても、そのビューを使用できます。つまり、ビューを作成して、ロールにテーブルのサブセットのみへのアクセス権を付与できるということです。たとえば、医療請求情報にはアクセスするが、同じテーブル内の医療診断情報にはアクセスしないビューを作成できます。次に、そのビューに対する権限を「経理」ロールに付与して、経理が患者の診断を見ずに請求情報を確認できるようにします。

  • 設計上、 SHOW VIEWS コマンドはセキュアビューに関する情報を提供しません。セキュアビューに関する情報を表示するには、Information Schemaの VIEWS ビューを使用し、ビューを所有するロールを使用する必要があります。

  • 再帰ビューは列名リストを提供する必要があります。

  • 再帰的ビューを定義するときは、無限再帰を防止してください。再帰ビュー定義の WHERE 句は、通常、データの階層の最終レベルを処理した後にデータを使い果たすことにより、再帰を最終的に停止できるようにする必要があります。

  • メタデータについて。

    注意

    Snowflakeサービスを使用する場合、お客様は、個人データ(ユーザーオブジェクト向け以外)、機密データ、輸出管理データ、またはその他の規制されたデータがメタデータとして入力されていないことを確認する必要があります。詳細については、 Snowflakeのメタデータフィールド をご参照ください。

  • 1つ以上のビュー列にマスキングポリシーを使用してビューを作成する場合、またはビューに行アクセスポリシーを追加する場合は、 POLICY_CONTEXT 関数を使用して、マスキングポリシーによって保護されている列と行アクセスポリシーによって保護されているビューに対するクエリをシミュレートします。

  • 同じロールがビューストリームとソースストリームの両方を所有している(つまり、同じロール、またはロール階層の下位ロールがビューストリームとソースストリームに対する OWNERSHIP 権限を持っている)場合を除き、ストリームをソースオブジェクトとして使用したビューを作成しないでください。代わりに、ソースオブジェクトとして追跡するオブジェクトを持つビューを作成します。次に、それらのビューにストリームを作成します。詳細については、 Streams on Views をご参照ください。

移植の注意

  • 一部のベンダーは FORCE キーワードをサポートしています。

    CREATE OR REPLACE FORCE VIEW ...
    
    Copy

    Snowflakeは FORCE キーワードを受け入れますが、サポートはしていません。つまり、このキーワードを使用しても構文エラーは発生しませんが、基になるデータベースオブジェクト(テーブルまたはビュー)がまだ存在しない場合は、 FORCE を使用してもビューの作成は強制されません。存在しないテーブルまたはビューのビューを作成しようとすると、 FORCE キーワードが使用されていてもエラーメッセージが表示されます。

  • ビューでテーブルを検索するとき、一部のベンダーはアクティブなスキーマで修飾されていないテーブル名を検索します。Snowflakeは、 ビューと同じスキーマ内 で、修飾されていないテーブル名を検索します。Snowflakeに移植するときは、完全修飾テーブル名を使用するようにビューを更新することを検討してください。

現在のスキーマに、テーブルからすべての行を選択するコメント付きのビューを作成します。

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 |
+---------------------------------+-------------------+----------+---------------+-------------+----------+-----------+--------------------------------------------------------------------------+
Copy

次の例は、ビューがセキュアであることを除いて、前の例と同じです。

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';
Copy

以下に、再帰ビューを作成する2つの方法を示します。

まず、テーブルを作成してロードします。

CREATE OR REPLACE TABLE employees (title VARCHAR, employee_ID INTEGER, manager_ID INTEGER);
Copy
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);
Copy

再帰 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
);
Copy
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          |
+----------------------------+-------------+------------+-----------------------------+----------------------------+
Copy

キーワード 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
);
Copy
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          |
+----------------------------+-------------+------------+-----------------------------+----------------------------+
Copy