【问题标题】:Filter column names from existing table for SQL DDL statement从 SQL DDL 语句的现有表中筛选列名
【发布时间】:2020-04-18 19:25:08
【问题描述】:

是否可以在 psql 中过滤列名本身?我想在单独的模式 a la(伪代码)中生成原始表的有限版本(有几百列):

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

【问题讨论】:

  • 你能提供样本数据和想要的结果吗?不清楚你真正想做什么。
  • 假设我有一个表 schema_1.original_table(A 文本、B 文本、C 文本)。我想运行类似 create table schema_2.new_table as select * from schema_1.original_table where column_name NOT IN (A, B);我基本上是想看看是否有办法从原始表中“取消选择”我不感兴趣的列,而不是在单个创建表查询中放下我感兴趣的所有 300 多个列名如果这是有道理的。
  • 据我所知,在 Postgres 中没有简单的方法可以做到这一点。
  • 我想的也差不多。在过去一两个小时的大部分时间里,一直在摆弄它。你知道一个不那么简单的方法会是什么样子吗?
  • 毕竟很简单...

标签: sql postgresql dynamic-sql


【解决方案1】:

动态构建 DDL 命令。您可以分两步完成:

  1. 构建语句:

    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. (检查它是否良好!)然后在服务器的第二次往返中执行生成的语句。

这是基于信息架构视图information_schema.columns。或者,您可以使用pg_catalog.pg_attribute。相关:

但它也可以在与服务器的单次往返中完成:

来自任何客户端的DO 声明

DO 只是一个简单的包装器,用于临时执行 PL/pgSQL 代码。你可以在函数或过程中做同样的事情。

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

使用 psql 元命令更简单\gexec

既然你提到了default interactive terminal psql。在那里你可以使用\gexec。它...

将当前查询缓冲区发送到服务器,然后将查询输出的每一行的每一列(如果有)视为要执行的 SQL 语句。

所以:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-21
    • 1970-01-01
    • 2011-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多