Создание таблицы с определенными столбцами из другой таблицы

#sql #postgresql

#sql #postgresql

Вопрос:

Допустим, у нас есть таблица A с 200 различными столбцами. Мы хотим выбрать столбцы, которые содержат определенную подстроку (например, подстроку «host» в «host_id», «host_name», «average_host_rating»), и создать новую таблицу B, содержащую только эти столбцы и их данные, импортированные из файла .csv.

Я попытался создать новую таблицу вручную, однако это не очень хорошая практика, и я хочу улучшить код, сделав его действительным и функциональным, даже если я добавлю больше столбцов в таблицу A.

Создание таблицы вручную:

 SELECT 
   listings.host_id,
   listings.host_url ,
   ..
   ..
   listings.host_name ,
   listings.host_since ,
INTO host_table
FROM listings
WHERE TRUE;
  

Попытка создать таблицу лучшим способом:

 CREATE TABLE B AS 
SELECT  *
FROM    A
WHERE  A::text LIKE '%host%'
  

Я ожидал, что он создаст таблицу B с каждым столбцом, который содержит ‘host’ в своем имени, однако он вернул точную копию таблицы A (и всех ее данных). Я пробовал разные способы создания новых таблиц, однако проблема всегда заключалась в том, что я не мог выделить только столбцы с указанной подстрокой (‘host’).

Что может быть не так в моем синтаксисе, способе мышления или чем-то еще? Заранее спасибо!

Ответ №1:

Вы можете создать и вызвать функцию с параметрами. Функция будет динамически выбирать столбцы из information_schema.columns .

Обратите внимание, что where false используется, потому что вы упомянули, что данные будут поступать из файла csv, а не из исходной таблицы.

 create or replace function 
   fn_gen_tab_text ( curr_tab_in text,tab_text_in TEXT, new_tab_in text)
 RETURNS void AS
  $body$
 declare v_sql TEXT;
  BEGIN
   select 'CREATE TABLE %I AS select ' || string_agg(column_name,',') 
        ||' from %I where false'
      into v_sql from information_schema.columns  
   where table_name = curr_tab_in
   and column_name like '%'||tab_text_in||'%';
   EXECUTE format (v_sql,new_tab_in,curr_tab_in);
 END $body$ language plpgsql 
  

Назовите это как

 select fn_gen_tab_text('host_table','host','new_table' );
  

ДЕМОНСТРАЦИЯ