UNION ALL во всех таблицах, начинающихся с определенной строки - PullRequest
1 голос
/ 06 ноября 2019

Я хотел бы объединить таблицы с одинаковыми именами в одну таблицу. Например, допустим, у меня есть база данных с таблицами «EXT_ABVD», «EXT_ADAD», «EXT_AVSA», «OTHER», и я хочу объединить все таблицы, начинающиеся с «EXT_», я хотел бы получить результат

select col1 ,col2 from EXT_ABVD
union all
select col1 ,col2 from EXT_ADAD
union all
select col1 ,col2 from EXT_AVSA;

Я хотел бы делать это регулярно (например, ежедневно), и каждый раз, когда он запускается, могут появляться новые таблицы, начинающиеся с 'EXT_'. Я не хочу обновлять запрос union_all вручную.

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

Ответы [ 2 ]

3 голосов
/ 06 ноября 2019

С учетом этих таблиц:

CREATE TABLE TEST_DB.PUBLIC.EXT_ABVD (col1 INTEGER, col2 INTEGER);
CREATE TABLE TEST_DB.PUBLIC.EXT_ADAD (col1 INTEGER, col2 INTEGER);
CREATE TABLE TEST_DB.PUBLIC.EXT_ADAQ (col1 INTEGER, col2 INTEGER);

Такое представление может быть динамически создано:

CREATE OR REPLACE VIEW TEST_DB.PUBLIC.union_view AS 
SELECT * FROM TEST_DB.PUBLIC.EXT_ABVD
 UNION ALL 
SELECT * FROM TEST_DB.PUBLIC.EXT_ADAD
 UNION ALL 
SELECT * FROM TEST_DB.PUBLIC.EXT_ADAQ

Используя эту процедуру:

create or replace procedure TEST_DB.PUBLIC.CREATE_UNION_VEIW(TBL_PREFIX VARCHAR)
  returns VARCHAR -- return final create statement
  language javascript
  as     
  $$
    // build query to get tables from information_schema
    var get_tables_stmt = "SELECT Table_Name FROM TEST_DB.INFORMATION_SCHEMA.TABLES \
            WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME LIKE '"+ TBL_PREFIX + "%';"

    var get_tables_stmt = snowflake.createStatement({sqlText:get_tables_stmt });

    // get result set containing all table names
    var tables = get_tables_stmt.execute();

    // to control if UNION ALL should be added or not
    // this could likely be handled more elegantly but i don't know JavaScript :)
    var row_count = get_tables_stmt.getRowCount();
    var rows_iterated = 0; 

    // define view name
    var create_statement = "CREATE OR REPLACE VIEW TEST_DB.PUBLIC.union_view AS \n";

    // loop over result set to build statement
    while (tables.next())  {
        rows_iterated += 1;

        // we get values from the first (and only) column in the result set
        var table_name = tables.getColumnValue(1); 

        // this will obviously fail if the column count doesnt match
        create_statement += "SELECT * FROM TEST_DB.PUBLIC." + table_name 

        // add union all to all but last row
        if (rows_iterated < row_count){
            create_statement += "\n UNION ALL \n"
        }
     }

    // create the view
    var create_statement = snowflake.createStatement( {sqlText: create_statement} );
    create_statement.execute();

    // return the create statement as text
    return create_statement.getSqlText();
  $$
  ;

Что бы мывызовите так: CALL CREATE_UNION_VIEW('EXT_A');

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

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

create or replace task create_union_task
  warehouse = COMPUTE_WH
  schedule = '1440 minute' -- once every day
as
  CALL CREATE_UNION_VIEW('EXT_A');
2 голосов
/ 06 ноября 2019

В настоящее время вы можете достичь этого только с помощью хранимой процедуры Snowflake .

Вы не указываете, как вы хотите использовать результат запроса, но удобным способомчерез VIEW. Таким образом, хранимая процедура должна сгенерировать определение VIEW, содержащее запрос в вашем вопросе.

...