Объединение нескольких таблиц - PullRequest
0 голосов
/ 25 апреля 2018

Я пытался следовать этому ответу

Динамический запрос UNION ALL в Postgres

но я получаю ОШИБКА: синтаксическая ошибка в или около "записи"

DECLARE
    rec record;
    strSQL text; 
BEGIN
    FOR
        rec in 
                select table_name
                from 
                    information_schema.tables
                where
                    table_name like 'history%' 

        loop
                strSQL : = strSQL || 'Select * from' || rec.table_schema ||'.'|| rec.table_name || ' UNION '; 
        end loop; 
 -- remove last ' UNION ' from strSQL  

--strSQL := 'Select row_number() over(order by rowid ) as row_num from (' || strSQL || ')';



execute strSQL;

У кого-нибудь есть идеи?

фон: Таблица истории перемещается каждую ночь в свою таблицу с добавленной датой.

Итак, history04242018 для каждого имени таблицы, есть ли лучший способ получить данные за несколько дней?

edit: в таблицах всегда будет одинаковое количество столбцов, поэтому объединение должно быть в порядке.

edit2: у меня есть доступ только для чтения.

обновление с предложением использования блока анонимного кода я теперь использую следующее:

DO   
    $$
declare
  strSQL text;
begin
  select
    string_agg(format('select * from %I.%I', table_schema, table_name), E' union\n')
    into strSQL
  from information_schema.tables
  where table_name like 'history%';


   execute strSQL ;
end $$;

однако теперь я получаю ошибку

Ошибка описания: не удалось получить план (ы) EXPLAIN: ОШИБКА: синтаксис ошибка в или около позиции "DO": 58

0 записей затронуто

1 Ответ

0 голосов
/ 25 апреля 2018

declare, for, loop, execute являются частями plpgsql, непрозрачные sql (declare может использоваться на равнине sql но в другом смысле). Поэтому вы должны заключить код в анонимный блок или в функцию , если вы хотите вернуть из него некоторые данные:

create function get_history(p_day int)
  returns table (<structure of history tables here>)
  -- or
  -- returns setof <history table name>
  language plpgsql
as $$
declare
  strSQL text;
begin
  select
    string_agg(format('select * from %I.%I', table_schema, table_name), E' union\n')
    into strSQL
  from information_schema.tables
  where table_name like to_char(p_day, '"history__"FM09%');

  return query execute strSQL;
end $$;

Также посмотрите на Разделение таблицы (выберите версию PostgreSQL в начале статьи).


Update

Однако есть несколько способов вернуть данные запроса из анонимного блока plpgsql без изменения схемы БД: курсоры и подготовленные операторы .

IMO второй немного проще, поэтому:

do $$
declare
  strSQL text;
begin
  select
    string_agg(format('select * from %I.%I', table_schema, table_name), E' union\n')
    into strSQL
  from information_schema.tables
  where table_name like to_char(p_day, '"history__"FM09%');

  -- Prepend "prepare", change the "foo" name as you wish
  strSQL := 'prepare foo as ' || strSQL;

  execute strSQL;
end $$;

-- Usage
execute foo;

-- And deallocate prepared statement when it does not need anymore:
deallocate foo;

Простой рабочий пример

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...