web-dev-qa-db-ja.com

CREATE TABLE AS SELECTを使用して、WITH条件(CTE)を指定するにはどうすればよいですか?

CREATE TABLE AS SELECT(CTAS)と呼ばれるSELECT ... INTO .... FROM より前の古い非推奨のコマンドがPostgreSQLにあり、WITH句/共通テーブル式(CTE)をサポートしています。たとえば、私はこれを行うことができます。

WITH w AS (
  SELECT *
  FROM ( VALUES (1) ) AS t(x)
)
SELECT *
INTO foo
FROM w;

しかし、私はこれを行うことはできません。

WITH w AS (
  SELECT *
  FROM ( VALUES (1) ) AS t(x)
)
CREATE TABLE foo AS
SELECT * FROM w;

または、私は得る

ERROR:  syntax error at or near "CREATE"
LINE 5: CREATE TABLE foo AS

標準化されたCTAS構文を使用して、どうすればよいでしょうか。

5
Evan Carroll

扱いにくいかもしれませんが、WITH句を先頭からクエリに移動する必要があります。これはテーブルを生成するステートメントの一部であり、そのステートメントはafterCREATE TABLEとなるため、この構文を使用します。

CREATE TABLE foo AS
WITH w AS (
  SELECT *
  FROM ( VALUES (1) ) AS t(x)
)
SELECT * FROM w;

notofficial docs、 で明示的であることも注目に値します==queryに該当します

CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name
    [ (column_name [, ...] ) ]
    [ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]
    [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
    [ TABLESPACE tablespace_name ]
    AS query
    [ WITH [ NO ] DATA ]

ドキュメントでは、2つのotherWITHキーワードの使用例に言及していますが、

  1. 設定するには storage_options
  2. NO DATAを設定するには

このように両方が使用されているのを確認できます。

CREATE TABLE foo
WITH (fillfactor = 100)
AS
  WITH w AS (
    SELECT *
    FROM ( VALUES (1) ) AS t(x)
  )
  SELECT * FROM w
WITH NO DATA;

これで何もないテーブルができました。

TABLE foo;
 x 
---
(0 rows)
7
Evan Carroll