Перебор таблиц для получения максимальных дат из созданного столбца дат в Postgres

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

SELECT MAX(z_date_creation)  
FROM table_schema.table_name

в наборе таблиц, которые я получаю с помощью

SELECT  
  c.table_schema,  
  c.table_name  
FROM information_schema."columns" c  
WHERE c.column_name LIKE '%z_date_creation'  
AND c.table_schema = 'datawarehouse'  
AND c.table_name NOT LIKE 'partition%'

а затем передать его в специальную таблицу «ods.dates_derniere_maj», по которой я буду подключать отчеты.

Я использую курсор как лучшую идею, чтобы перебирать таблицы, в которых нужно получить MAX(z_date_creation). Мне удается передать значения table_schema и table_name в мою таблицу ods.dates_derniere_maj, но я не могу найти способ также получить MAX(z_date_creation) из этих таблиц.

Я застрял с частью вложенного запроса.

Вот что я придумал до сих пор:

DO $$  
DECLARE  
    table_rec record ;  
    max_date TEXT DEFAULT NOW();  
    cursor1 CURSOR FOR  
      SELECT DISTINCT c.table_schema, c.table_name, c.column_name  
      FROM information_schema."columns" c  
      WHERE c.table_schema = 'datawarehouse'  
      AND c.table_name NOT LIKE 'partition%'  
      AND c.column_name LIKE '%creation%';  
    from_clause TEXT;  
    date_column TEXT;  
BEGIN  
  FOR table_rec IN cursor1
  LOOP  
  from_clause := CONCAT(table_rec.table_schema, '.', table_rec.table_name);  
  date_column := CONCAT(table_rec.table_schema, '.', table_rec.table_name,'.','z_date_creation');  

Which code herebelow ?

PREPARE nom_req (text, text) AS  
  SELECT MAX($1) FROM $2 ; ---> not working, syntax error on $2  
max_date := EXECUTE nom_req (date_column, from_clause) ; ---> not working  
  SELECT MAX(date_column) INTO max_date FROM CONCAT(from_clause) ; ----> not working  
 
INSERT INTO ods.dates_derniere_maj (schema_name, table_name, z_date_creation_max)  
    VALUES (table_rec.table_schema, table_rec.table_name, max_date);  
END LOOP;  
END $$;`

Я попытался передать переменные table_rec.table_schema и table_rec.table_name непосредственно в предложении FROM, но это не сработало, поэтому я попытался объединить их заранее.

Любая помощь будет высоко ценится !

Огромное спасибо !

Франк

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
52
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Попробуйте что-то вроде этого:

CREATE FUNCTION max_date() RETURNS date LANGUAGE plpgsql AS
$$
DECLARE
  table_rec record ;
  max_date date ;
  result date ;
  cursor1 CURSOR FOR  
      SELECT DISTINCT c.table_schema, c.table_name, c.column_name  
      FROM information_schema."columns" c  
      WHERE c.table_schema = 'datawarehouse'  
      AND c.table_name NOT LIKE 'partition%'  
      AND c.column_name LIKE '%creation%';  
BEGIN
  FOR table_rec IN cursor1
  LOOP  
    EXECUTE FORMAT( 'SELECT max(%I) FROM %I.%I'
                  , table_rec.column_name
                  , table_rec.table_schema
                  , table_rec.table_name
                  ) 
    INTO max_date ;
    result = greatest(result, max_date) ;
  END LOOP ;
  RETURN result ;
END ;
$$ ;

см. результат теста в dbfiddle

Большое спасибо @edouard! Мне не хватало пункта FORMAT. Это сработало отлично! 💪

Franck BERNERON 23.01.2023 12:36

Вот что я придумал с неоценимой помощью Эдуарда!

DO $$ 
DECLARE
    table_rec record ;
    max_date TEXT DEFAULT NOW();
    cursor1 CURSOR FOR SELECT DISTINCT c.table_schema, c.table_name, c.column_name
            FROM information_schema."columns" c
            WHERE c.table_schema = 'datawarehouse'
            AND c.table_name NOT LIKE 'partition%'
            AND c.column_name LIKE '%creation%';

BEGIN 
    FOR table_rec IN cursor1
    LOOP
        EXECUTE FORMAT( 'SELECT max(%I) FROM %I.%I'
                      , table_rec.column_name
                      , table_rec.table_schema
                      , table_rec.table_name
                      ) 
        INTO max_date ;
        INSERT INTO ods.dates_derniere_maj (schema_name, table_name, z_date_creation_max)
            VALUES (table_rec.table_schema, table_rec.table_name, max_date);
    END LOOP;
END $$;

Другие вопросы по теме