Как создать несколько временных таблиц, используя записи из CTE, которые мне нужно вызывать несколько раз в процедуре Postgres plpgsql?

#postgresql #stored-procedures #plpgsql #common-table-expression #postgresql-9.4

Вопрос:

ОБНОВЛЕНИЕ: Я использую CTE, потому что я использую ЦИКЛ для цикла партиями по 10000.

Я уже использую выражение CTE в процедуре plpgsql для захвата некоторых внешних ключей из (1) определенной таблицы, мы можем ее вызвать master_table . Я создал совершенно новую таблицу, которую мы можем назвать этой таблицей table_with_fks , в моих операторах DDL, поэтому в этой таблице содержатся FKS, которые я извлекаю и сохраняю.

Позже я беру эти FK из своей table_with_fks и ОБЪЕДИНЯЮ с другими таблицами в своей базе данных, чтобы получить всю исходную запись (полную запись со всеми столбцами из соответствующей таблицы) и вставить ее в архивную таблицу.

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

Мой пример CTE:

 LOOP
   EXIT WHEN some_condition;

WITH fk_list_cte AS (
  SELECT mt.fk1, mt.fk2, mt.fk3, mt.fk4
  FROM master_table mt
  WHERE mt.created_date < now() - interval '365' // archive record if >= 1 year old
  LIMIT 10000
)
INSERT INTO table_with_fks (SELECT * FROM fk_list_cte);
commit;

END LOOP;
 

Теперь у меня есть (4) другие процедуры, которые JOIN на каждом FK в этом table_with_fks с его родительской таблицей, на которую он ссылается. Я делаю это, потому что, как я уже сказал, сначала я получил только FK, и у меня нет всех исходных столбцов для записи. Поэтому я сделаю что-то вроде

 LOOP
   EXIT WHEN some_condition;

WITH full_record_cte AS (
  SELECT * 
  FROM table_with_fks fks
  JOIN parent_table1 pt1
  ON fks.fk1 = pt1.id
  LIMIT 10000),
  INSERT INTO (select * from full_record_cte);
  commit;

END LOOP;
 

NOW, what I want to do, is instead of having to RE-JOIN 4 times later on these FK’s that are found in my table_with_fks , I want to use the first CTE fk_list_cte to JOIN on the parent tables right away and grab the full record from each (4) tables and put it in some TEMP postgres table. I think I will need (4) unique TEMP tables, as I don’t know how it would work if I combine all their data into one BIG table, because each table has different data/different columns.

Есть ли способ использовать исходный CTE fk_list_cte и вызывать его несколько раз подряд, а сразу после этого создать 4 временные таблицы, все из которых используют исходный CTE? пример:

 LOOP
   EXIT WHEN some_condition;

WITH fk_list_cte AS (
  SELECT mt.fk1, mt.fk2, mt.fk3, mt.fk4
  FROM master_table mt
  WHERE mt.created_date < now() - interval '365' // archive record if >= 1 year old
  LIMIT 10000
),
WITH fetch_fk1_original_record_from_parent AS (
  SELECT * 
  FROM fk_list_cte cte
  JOIN parent_table1 pt1
  ON  cte.fk1 = pt1.id
),
WITH fetch_fk2_original_record_from_parent AS (
  SELECT * 
  FROM fk_list_cte cte
  JOIN parent_table2 pt2
  ON  cte.fk2 = pt2.id
),
WITH fetch_fk3_original_record_from_parent AS (
  SELECT * 
  FROM fk_list_cte cte
  JOIN parent_table3 pt3
  ON  cte.fk3 = pt3.id
),
WITH fetch_fk4_original_record_from_parent AS (
  SELECT * 
  FROM fk_list_cte cte
  JOIN parent_table4 pt4
  ON  cte.fk4 = pt4.id
),
CREATE TEMPORARY TABLE fk1_tmp_tbl AS (
  SELECT * 
  FROM fetch_fk1_original_record_from_parent
)
CREATE TEMPORARY TABLE fk2_tmp_tbl AS (
  SELECT * 
  FROM fetch_fk2_original_record_from_parent
)
CREATE TEMPORARY TABLE fk3_tmp_tbl AS (
  SELECT * 
  FROM fetch_fk3_original_record_from_parent
)
CREATE TEMPORARY TABLE fk4_tmp_tbl AS (
  SELECT * 
  FROM fetch_fk4_original_record_from_parent
);

END LOOP;
 

Я знаю, что 4 CREATE TEMPORARY TABLE утверждения определенно не будут работать (могу ли я создать 4 временные таблицы одновременно/одновременно?) . Кто-нибудь видит логику того, что я пытаюсь здесь сделать, и может мне помочь?

Комментарии:

1. Возможно, используйте ON COMMIT DROP временные таблицы вместо CTE.

2. @LaurenzAlbe Я использовал CTE, потому что я использую ЦИКЛ для цикла в партиях по 10000 (предел = 10000)

3. @LaurenzAlbe Так. Я предполагаю, что я мог бы создать временные таблицы вне цикла, тогда мне нужно всего лишь выбрать В simulatenous/одновременно 4 раза, вызывая исходный CTE?