PostgreSQL: Create table if not exists AS

后端 未结 6 1288
不思量自难忘°
不思量自难忘° 2020-12-29 04:54

I\'m using PostgreSQL and am an SQL beginner. I\'m trying to create a table from a query, and if I run:

CREATE TABLE table_name AS
   (....query...)
<         


        
相关标签:
6条回答
  • 2020-12-29 05:05

    CTAS (Create Table AS) for REDSHIFT PLPGSQL flavor. Shout out to Erwin Brandstetter for the root idea using pure PG syntax.

    CREATE
    OR
    REPLACE
    PROCEDURE pipeline.sp_create_table_if_not_exists_as (sch VARCHAR, tbl VARCHAR, qry VARCHAR, tbl_attrs VARCHAR)
     AS
        /*
         specifically an exception for CTAS functionality: https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_TABLE_AS.html
        */
    $$
    BEGIN
    
    IF EXISTS (
       SELECT 1
       FROM   pg_catalog.pg_class c
       JOIN   pg_catalog.pg_namespace n ON n.oid = c.relnamespace
       WHERE  n.nspname = sch
       AND    c.relname = tbl
       ) THEN
    
       RAISE INFO 'Table already exists: %.%', sch, tbl;
    ELSE
        EXECUTE 'CREATE TABLE ' || sch || '.' || tbl || ' ' || tbl_attrs || ' AS ' || qry;
        RAISE INFO 'Table created successfully: %.%, using query: [%], optional attributes: [%]', sch, tbl, qry, tbl_attrs;
    END IF;
    
    END;
    $$
    language plpgsql;
    
    0 讨论(0)
  • 2020-12-29 05:12

    Try this,

    create or replace function create_table(tblname text) returns text as
    $$ 
    BEGIN
    $1 = trim($1);
    IF not EXISTS (select relname from pg_stat_user_tables where relname =$1) THEN
    execute 'create table '||$1||' as select * from tbl'; -- <put your query here>
    return ''||$1||' Created Successfully !!';
    else
    return  ''||$1||' Already Exists !!';
    END IF;
    END
    $$
    language plpgsql 
    

    create or replace function create_table_qry(tblname text,qry text) returns text as
    $$ 
    BEGIN
    $1 = trim($1);
    IF not EXISTS (select relname from pg_stat_user_tables where relname =$1) THEN
    execute 'create table '||$1||' as '||$2||'';
    return ''||$1||' Created Successfully !!';
    else
    return  ''||$1||' Already Exists !!';
    END IF;
    END
    $$
    language plpgsql 
    
    0 讨论(0)
  • 2020-12-29 05:15

    If you are going to write a function for this, base it on system catalog table pg_class, not on views in the information schema or the statistics collector (which only exist if activated).

    • How to check if a table exists in a given schema

    CREATE OR REPLACE FUNCTION create_table_qry(_tbl text
                                              , _qry text
                                              , _schema text = NULL)
      RETURNS bool AS
    $func$
    DECLARE
      _sch text := COALESCE(_schema, current_schema());
    BEGIN
    
    IF EXISTS (
       SELECT 1 
       FROM   pg_catalog.pg_class c
       JOIN   pg_catalog.pg_namespace n ON n.oid = c.relnamespace
       WHERE  n.nspname = _sch
       AND    c.relname = _tbl
       ) THEN
    
       RAISE NOTICE 'Name is not free: %.%',_sch, _tbl;
       RETURN  FALSE;
    ELSE
    EXECUTE format('CREATE TABLE %I.%I AS %s', _sch, _tbl, _qry);
    
       RAISE NOTICE 'Table created successfully: %.%',_sch, _tbl;
       RETURN  TRUE;
    END IF;
    
    END
    $func$  LANGUAGE plpgsql;
    

    The function takes a table name and the query string, and optionally also a schema to create the table in (defaults to the current schema).

    Note the correct use of = in the function header and := in the function body:

    • The forgotten assignment operator "=" and the commonplace ":="

    Also note how identifiers are escaped as identifiers. You can't use regclass, since the table does not exist, yet:

    • Table name as a PostgreSQL function parameter
    0 讨论(0)
  • 2020-12-29 05:16

    It’s simple:

     CREATE TABLE IF NOT EXISTS abc ( sql_id BIGINT(20) NOT NULL
       AUTO_INCREMENT PRIMARY KEY, sender VARCHAR(20) NULL)
    
    0 讨论(0)
  • 2020-12-29 05:20

    Use do :

    do $$ begin
    
    if not exists (  SELECT 1
       FROM   information_schema.tables 
       WHERE  table_schema = 'schema_name'
       AND    table_name = 'bla ') then
    
      create table schema_name.bla as select * from blu;
    end if;
    
    end $$;
    
    
    0 讨论(0)
  • 2020-12-29 05:22

    CREATE TABLE AS is considered a separate statement from a normal CREATE TABLE, and until Postgres version 9.5 (see changelog entry) didn't support an IF NOT EXISTS clause. (Be sure to look at the correct version of the manual for the version you are using.)

    Although not quite as flexible, the CREATE TABLE ... LIKE syntax might be an alternative in some situations; rather than taking its structure (and content) from a SELECT statement, it copies the structure of another table or view.

    Consequently, you could write something like this (untested); the final insert is a rather messy way of doing nothing if the table is already populated:

    CREATE OR REPLACE VIEW source_data AS SELECT * FROM foo NATURAL JOIN bar;
    
    CREATE TABLE IF NOT EXISTS snapshot LIKE source_data;
    
    INSERT INTO snapshot
    SELECT * FROM source_data
    WHERE NOT EXISTS ( SELECT * FROM snapshot );
    

    Alternatively, if you want to discard previous data (e.g. an abandoned temporary table), you could conditionally drop the old table, and unconditionally create the new one:

    DROP TABLE IF EXISTS temp_stuff;
    
    CREATE TEMPORARY TABLE temp_stuff AS SELECT * FROM foo NATURAL JOIN bar;
    
    0 讨论(0)
提交回复
热议问题