2015-09-24 1 views
1

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

Этот запрос дает мне список таблиц мне нужно:

SELECT table_name 
FROM information_schema.tables 
WHERE table_schema = 'abc_dev_12345' 
AND table_name like 'fact_%'; 

Для списка таблиц данных, то я хочу, чтобы сделать счет от каждого table_name (каждый table_name имеет ту же самую информацию о колонке Мне нужно запрос)

SELECT table_name, 
     count (domain_key) key_count, 
     domain_key, 
     form_created_datetime 
FROM (List of tables above) 
GROUP BY domain_key, 
     form_created_datetime; 

Можно ли перебирать каждую таблицу, указанную в первом запросе, для выполнения моего подсчета? Сделайте это в одном запросе?

Так ожидается выход будет похож на это:

table_name | key_count | domain_key | form_created_datetime 
-------------------------------------------------------------- 
fact_1  1241     5 2015-09-22 01:47:36.136789 
fact_2   32     9 2015-09-22 01:47:36.136789 

Пример данных:

abc_dev_12345=> SELECT * 
FROM information_schema.tables 
where table_schema='abc_dev_own_12345' 
and table_name='fact_1'; 
table_catalog | table_schema |  table_name  | table_type | self_referencing_column_name | reference_generation | user_defined_type_catalog | user_defined_type_schema | use 
r_defined_type_name | is_insertable_into | is_typed | commit_action 
---------------+-------------------+--------------------+------------+------------------------------+----------------------+---------------------------+--------------------------+---- 
--------------------+--------------------+----------+--------------- 
abc_dev_12345 | abc_dev_own_12345 | fact_1 | BASE TABLE |        |      |       |       | 
        | YES    | NO  | 
(1 row) 


abc_dev_12345=> SELECT column_name 
FROM information_schema.columns 
WHERE table_schema = 'abc_dev_own_12345' 
    AND table_name = 'fact_1'; 
     column_name 
------------------------ 
email_date_key 
email_time_key 
customer_key 
form_created_datetime 
client_key 
domain_key 
+0

ли INFORMATION_SCHEMA.TABLES имеет domain_key колонки и form_created_datetime? Можете ли вы предоставить некоторые примеры данных из списка таблиц вместе с другими значениями столбцов, которые вы хотите? – Utsav

+0

Я думаю, я могу запросить информацию для имен столбцов этих же таблиц тоже? – noober

+0

Извините, я не знаю postgresql. Но если вы можете показать некоторые данные из информационных_схем.tables, которые соответствуют вашему желаемому результату, я могу помочь вам с запросом. – Utsav

ответ

1

Как Eelke и Craig Ringer отметил, вам нужен динамический запрос в plpgsql функции. Основное заявление вы хотите применить к каждой таблице:

SELECT <table_name>, count(domain_key) AS key_count, domain_key, form_created_datetime 
FROM <table_name> GROUP BY 3, 4 

и вы хотите UNION партии вместе.

Самый эффективный способ сделать это - сначала построить запрос как объект text из информации в information_schema.tables, а затем EXECUTE этот запрос. Там не много способов, чтобы построить этот запрос, но мне особенно нравится ниже подвох с string_agg():

CREATE FUNCTION table_domains() 
RETURNS TABLE (table_name varchar, key_count bigint, domain_key integer, form_created_datetime timestamp) 
AS $$ 
DECLARE 
    qry text; 
BEGIN 
    -- format() builds query for individual table 
    -- string_agg() UNIONs queries from all tables into a single statement 
    SELECT string_agg(
    format('SELECT %1$I, count(domain_key), domain_key, form_created_datetime 
      FROM %1$I GROUP BY 3, 4', table_name), 
    ' UNION ') INTO qry 
    FROM information_schema.tables 
    WHERE table_schema = 'abc_dev_12345' 
    AND table_name LIKE 'fact_%'; 

    -- Now EXECUTE the query 
    RETURN QUERY EXECUTE qry; 
END; 
$$ LANGAUGE plpgsql; 

Нет необходимости в петли или курсоры так довольно эффективные.

использования, как и любой другой стол:

SELECT * FROM table_domains(); 
+0

Спасибо за помощь. Я пытаюсь создать функцию сейчас, но получаю это.Не уверен, откуда это происходит: 'psql: crTestFunction.sql: 20: ОШИБКА: синтаксическая ошибка в точке или рядом с" qry " LINE 18: RETURN QUERY qry;' – noober

+1

Попробуйте «ВОЗВРАТИТЬ ЗАПРОС QUERY EXECUTE». – Patrick