Упростить сложное объединение всего в PostgreSQL - PullRequest
0 голосов
/ 14 августа 2010

У меня очень сложный запрос в PostgreSQL, который объединяет несколько таблиц, у всех из которых есть общий набор полей, которые мы хотим объединить.В настоящее время мы создаем этот запрос.Я видел решение этой проблемы с помощью UNPIVOT, и мне интересно, возможно ли это сделать в разновидности SQL PostgreSQL.

У меня есть что-то вроде

SELECT a,b,c FROM a UNION ALL
SELECT a,b,c FROM c UNION ALL
SELECT a,b,c FROM d UNION ALL
SELECT a,b,c FROM e UNION ALL
SELECT a,b,c FROM f

Я бы хотелиметь имена таблиц для объединения в отдельную таблицу и использовать их для этого запроса.

PS.Изменение схемы не вариант.

Ответы [ 2 ]

3 голосов
/ 14 августа 2010

Использовать наследование для документации Postgres для Наследование . Вам нужно будет заново создать базу данных, но это легко, если вы создадите дамп таблицы без схемы, создадите новую схему с наследованием и загрузите данные обратно.

Схема будет выглядеть примерно так:

CREATE TABLE base (a, b, c);
CREATE TABLE a () INHERITS (base);
CREATE TABLE b () INHERITS (base);
....

С этим дизайном вы можете сделать простой выбор:

SELECT * FROM base;

Это вернет все строки в base и все таблицы, наследуемые от base.

Прочтите о таблице PostgreSQL выделение из документов, если вы еще этого не сделали.

2 голосов
/ 16 августа 2010

Если вы действительно не можете исправить свой дизайн (или не хотите использовать очень хорошее предложение от jmz), ваш единственный выбор - это, вероятно, функция возврата набора, которая создает необходимый UNION "на лету", а затем возвращаетрезультаты этого.

create or replace function my_union()
 returns table(a integer, b integer, c integer)
as
$body$
declare
  union_cursor refcursor;
  table_cursor cursor for SELECT table_name FROM union_source; 
  union_query text := '';
begin

  -- build the query string for the union
  for table_list_record in table_cursor loop
    if union_query  '' then 
      union_query := union_query||' UNION ALL';
    end if;
    union_query := union_query||' SELECT a,b,c FROM '||table_list_record.table_name;
  end loop;

  -- run the union and return the result
  for a,b,c IN EXECUTE union_query LOOP
    return next;
  end loop; 
end;
$body$
language plpgsql;

Функция создает необходимый UNION на основе имен таблиц в union_source, а затем выполняет объединение и возвращает результат.

Вы можете расширить таблицу union_source и сохранить список столбцов для каждой таблицы, если столбцы не всегда имеют одинаковые имена.

Чтобы использовать эту функцию, просто выберите из нее:

select *
from my_union()
...