Filter column names from existing table for SQL DDL statement

醉酒当歌 提交于 2021-02-10 14:53:18

问题


Is it possible to filter on column names themselves in psql? I want to generate a limited version of the original table (with several hundred columns) in a separate schema a la (pseudocode):

create table why.am_i_doing_this
    select *
    from original.table 
    where column_name_of_the_table not in ('column_1', 'column_2' );

回答1:


Build the DDL command dynamically. You can do it in two steps:

  1. Build statement:

    SELECT 'CREATE TABLE why.am_i_doing_this AS SELECT '
        || string_agg(column_name, ', ' ORDER BY ordinal_position)
        || ' FROM original.table'
    FROM   information_schema.columns
    WHERE  table_schema = 'original'
    AND    table_name = 'table'
    AND    column_name NOT IN ('column_1', 'column_2');
    
  2. (Check it's good!) Then execute the generated statement in a second round trip to the server.

This is based on the information schema view information_schema.columns. Alternatively, you could use pg_catalog.pg_attribute. Related:

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

But it can be done in a single round trip to the server, too:

With a DO statement from any client

DO is just a simple wrapper for ad-hoc execution of PL/pgSQL code. You might do the same in a function or procedure.

DO
$$
BEGIN
   EXECUTE (
   SELECT 'CREATE TABLE why.am_i_doing_this AS SELECT '
       || string_agg(column_name, ', ' ORDER BY ordinal_position)
       || ' FROM original.table'
   FROM   information_schema.columns
   WHERE  table_schema = 'original'
   AND    table_name = 'table'
   AND    column_name NOT IN ('column_1', 'column_2')
   );
END
$$;

Simpler with psql meta-command \gexec

Since you mentioned the default interactive terminal psql. There you can use \gexec. It ...

Sends the current query buffer to the server, then treats each column of each row of the query's output (if any) as a SQL statement to be executed.

So:

SELECT 'CREATE TABLE why.am_i_doing_this AS SELECT '
    || string_agg(column_name, ', ' ORDER BY ordinal_position)
    || ' FROM original.table'
FROM   information_schema.columns
WHERE  table_schema = 'original'
AND    table_name = 'table'
AND    column_name NOT IN ('column_1', 'column_2')\gexec


来源:https://stackoverflow.com/questions/61294986/filter-column-names-from-existing-table-for-sql-ddl-statement

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!