[РЕШЕНО] Выборка из таблиц с определённым префиксом. Как ?

Здравствуйте!

Если скажем, буду создавать таблицы с префиксом test_, как мне правильно сделать запрос, для выборки из таблиц имена которых начинаются с '^test_' ?

Я нашёл инфу для получения имён таких таблиц, но как выбрать из них - не соображу (в силу неопытности):

SELECT relname FROM pg_class WHERE relname LIKE 'test_%' AND relkind = 'r';

Опции просмотра комментариев

Выберите предпочитаемый вами способ показа комментариев и нажмите "Сохранить настройки" для активации изменений.

Выбрать из них точно также

Выбрать из них точно также как из самых обычных таблиц. Собственно вы это уже продемонстрировали запросом из таблицы pg_class, которая имеет префикс pg_ :)

Пробовал, но ничего не

Пробовал, но ничего не получается.

Не могли бы вы дать ещё подсказку, или готовое решение ?

Вот простейшие таблицы:

CREATE TABLE test_001(id serial PRIMARY KEY, name text);
INSERT INTO test_001(name) VALUES('test_001');
 
CREATE TABLE test_002(id serial PRIMARY KEY, name text);
INSERT INTO test_002(name) VALUES('test_002');

Вот даже пробовал функцию написать, которая бы возвращала список таблиц а потом выбрать:

CREATE OR REPLACE FUNCTION list(text) RETURNS text AS $$
DECLARE
ret text;
BEGIN
SELECT relname INTO ret FROM pg_class WHERE relname LIKE CONCAT($1, '%') AND relkind = 'r';
RETURN ret;
END;
$$ LANGUAGE plpgsql;

Но `list' возвращает лишь одно имя первой таблицы, и выбрать из результата функции у меня не получилось:

SELECT list('test_'); --- возвращает одну запись `test_001'
SELECT id, name FROM list('test_'); --- выдаёт ошибку ...

PS: оч нужно найти решение, а то не охота создавать одну большую таблицу (для порядка 5 миллионов записей - не сразу, но БД будет расти), - критично время выполнения запроса, вот и хочу создать несколько десятков таблиц (~ 50), и дёргать оттуда данные (в частности и из всех этих таблиц с префиксом вместе взятых)...

Буду благодарен любой вашей помощи.

спасибо! ну или как вариант,

спасибо!

ну или как вариант, можно формировать строку запроса типа:

char query[1024];
char tmp[64];
strcpy(query, "SELECT id, name FROM");
FOR(int i=0;i<10;i++){
sprintf(tmp, " test_%03d", i);
strcat(query, tmp);
IF(i != 9) strcat(query,",");
}
strcpy(query, ";");

Конечно хотелось как-то элегантнее решить задачу, и на SQL, но нет, на c/c++ придётся..

СПАСИБО за ответы!

вы можете использовать

вы можете использовать EXECUTE если необходимо использовать имена, генерируемые на ходу. За справкой отсылаю в документацию

СПАСИБО за подсказку! Вот

СПАСИБО за подсказку!

Вот решение (вдруг кому понадобится):

--- создаём таблицы, и вставляем в каждую по одной записи:
CREATE TABLE test_001(id serial PRIMARY KEY, name varchar(32));
INSERT INTO test_001(name) VALUES('test_001');
 
CREATE TABLE test_002(id serial PRIMARY KEY, name varchar(32));
INSERT INTO test_002(name) VALUES('test_002');
 
 
--- вот собственно и сама функция:
CREATE OR REPLACE FUNCTION prefixed_query(varchar) RETURNS TABLE(id integer , name varchar(32)) AS $$
DECLARE
rec RECORD;
query text;
first BOOLEAN;
BEGIN
 
query := '';
first := false;
 
FOR rec IN SELECT relname FROM pg_class WHERE relname LIKE CONCAT($1, '%') AND relkind = 'r'
LOOP
 
IF first THEN
query := query || ' UNION ALL ';
ELSE
first := true;
END IF;
 
query := query || 'SELECT * FROM ' || quote_ident(rec.relname);
 
END LOOP;
 
query := query || ';';
RETURN QUERY EXECUTE query;
 
END;
$$ LANGUAGE plpgsql;

Использование функции:
SELECT * FROM prefixed_query('test_');

Вывод:
---------------------
| id | name |
-------+-------------
| 1 | test_001|
| 1 | test_002|
---------------------

PS: Ещё раз спасибо за помощь!

Опции просмотра комментариев

Выберите предпочитаемый вами способ показа комментариев и нажмите "Сохранить настройки" для активации изменений.

Back to top

(С) Виктор Вислобоков, 2008-2023