Snowflake cloud data platform 在Snowflake中将多个表合并为一个表

Snowflake cloud data platform 在Snowflake中将多个表合并为一个表,snowflake-cloud-data-platform,Snowflake Cloud Data Platform,假设我有以下每月表格,表格名称的格式是下划线后的数字表示月份。我想做的是将这12个表合并成一个表,而不必编写10-30条insert/union all语句 table_1 table_2 table_3 table_4 table_5 table_6 table_7 table_8 table_9 table_10 table_11 table_12 -- (only 12 in this instance but could be as many as 36) 我目前的方法是首先使用表1中

假设我有以下每月表格,表格名称的格式是下划线后的数字表示月份。我想做的是将这12个表合并成一个表,而不必编写10-30条insert/union all语句

table_1
table_2
table_3
table_4
table_5
table_6
table_7
table_8
table_9
table_10
table_11
table_12 -- (only 12 in this instance but could be as many as 36)
我目前的方法是首先使用表1中的数据创建主表

然后使用变量,这样我就可以一直点击run按钮,直到它与表_13的错误不存在为止

注:所有月表都有一个月id列


当然,与多次插入相比,它在控制台上节省了一些空间,但我仍然需要运行12次。雪花任务是我可以使用的吗?我无法从他们的文档中找到一个合适的例子来编写代码,但是,如果有人在这方面取得了成功,或者使用基于Javascript的SP解决了类似的问题,请说明。

您不能在这12个表之上创建一个视图吗。视图将是所有这些表的并集

根据下面的评论,我进一步阐述了我的答案。请尝试这种方法。当您的桌子很大时,它将提供更好的性能。分区将提高性能。这是基于实际经验

CREATE TABLE SALES_2000 (REGION VARCHAR, UNITS_SOLD NUMBER);
CREATE TABLE SALES_2001 (REGION VARCHAR, UNITS_SOLD NUMBER);
CREATE TABLE SALES_2002 (REGION VARCHAR, UNITS_SOLD NUMBER);
CREATE TABLE SALES_2003 (REGION VARCHAR, UNITS_SOLD NUMBER);

INSERT INTO SALES_2000 VALUES('ASIA', 25);
INSERT INTO SALES_2001 VALUES('ASIA', 50);
INSERT INTO SALES_2002 VALUES('ASIA', 55);
INSERT INTO SALES_2003 VALUES('ASIA', 65);

CREATE VIEW ALL_SALES AS
SELECT * FROM SALES_2000
UNION
SELECT * FROM SALES_2001
UNION
SELECT * FROM SALES_2002
UNION
SELECT * FROM SALES_2003;


SELECT * FROM ALL_SALES WHERE UNITS_SOLD = 25;

下面是一个存储过程,它将从表1到表12上的选择插入到主表中。根据需要修改:

create or replace procedure FILL_MASTER_TABLE()
returns string
language javascript
as
$$
    var rows = 0;
    for (var i=1; i<=12; i++) {
        rows += insertRows(i);
    }
    return rows + " rows inserted into master_table_1_12.";

// End of main function

function insertRows(i) {

sql = 
`insert into master_table_1_12 
select * 
from table_${i};`;

return doInsert(sql);
}

function doInsert(queryString) {
    var out;
    cmd1 = {sqlText: queryString};
    stmt = snowflake.createStatement(cmd1);
    var rs = stmt.execute();;
    rs.next();
    return rs.getColumnValue(1);
}
$$;

call fill_master_table();
对于我的用例,我最终创建了一个UDF,它为匹配我在select查询中指定的模式的表抛出一个CREATEVIEW语句。我使用的表有一个非常特定的命名约定,如下所示,类似表的唯一区别是u和m之间的数字。这对我来说很有效,但你的里程数可能会有所不同

sales_division_123m
sales_division_124m
sales_division_125m
....
我创建函数-

create or replace function combine_tables (table_pattern varchar(100))
returns table ("" varchar(10000)) as --empty header for easy copying and pasting

$$  
(
select 'create or replace view named_whatever as'
union all
select  concat('select * from ' , 
                lower(table_name), 
                case when table_name < max(table_name) over() then ' union all' 
                     else ';' end)
from warehouse_name.information_schema.tables
where table_name ilike table_pattern
order by 1
)
$$;
输出


我可以调整该函数,使其根据合并表的范围为视图提供合适的名称,例如master_sales_division_123m_125m,但为了灵活性,我省略了该部分。

您能解释一下您试图解决的问题吗?将12个类似的select语句合并在一起并将结果插入另一个表中是很简单的,并且需要花费不到一分钟的时间来编写-因此不清楚您是否还面临其他问题?您可以创建一个带有循环的JavaScript存储过程来完成此操作。如果你想要样品,请告诉我。@GregPavlik那太好了helpful@NickW不仅仅是一个问题,我正在寻找一种更简单/不太详细的方法来组合多个表,而不使用多个INSERT/union all语句。我在想雪花中的任务是否可以用于此,但找不到合适的示例。我也不知道基于循环的解决方案的Javascript。这似乎是很有可能的,只是可能没有一个雪花本机解决方案取决于您,当然,我理解如果您的实际用例比您在本文中给出的示例更复杂,但是考虑到使用多个insert语句来实现这一点是多么微不足道,我怀疑使用SP或任务的任何解决方案都不能被描述为更简单谢谢您提供了这个示例!我必须修改返回rs.getColumnValue1中的1吗?不,它只返回插入的行数。此外,我更新了我的答案。如果只合并表而不进行任何其他处理,则可以执行第二个代码示例。这并不能回答问题。若要评论或要求作者澄清,请在其帖子下方留下评论。-我认为它确实回答了这个问题,这就是我解决类似问题的方法。我的表是一个大表的分区。每个表格包含特定年份的数据,例如T1_2000、T1_2001等,。。。。我在这些表的顶部创建了一个视图来合并所有表。snowflake的美妙之处在于,当我用year添加where子句时,它确切地知道它需要使用哪个年份分区。您的答案通常是可以的,但是,OP清楚地说明了我要做的是将这12个表合并成一个表,而不必编写10-30 insert/union all语句您不需要插入。您已经将这些表填充到了较小的表中。在较小的分区表上创建视图时,雪花元数据缓存会跟踪每个表的最小/最大值。因此,当您在视图上进行选择时,它会直接进入数据所在的表。我已经详细阐述了答案来解释这一点。我知道我应该解释得更好。没有理由不使用UNION。事实上,对于一张大桌子来说,如果你像这样分开,它会给你更好的感觉performance@RajibDeb对不起,如果我的问题被误解了。我正在寻找一种解决方案/替代方案,而不是我已知的union all/multiple Insert。它需要更少的人工输入,而不是每次需要合并表时手动指定表名。我可以使用CTE、视图或使用union all或inserts的临时表,b 但是我仍然需要输入表1到表N,这就是我试图找到的解决方案。在表的命名方式中利用模式的解决方案。
insert into master_table_1_12 
select * from table_1
    union all
select * from table_2
    union all
select * from table_3
    union all
select * from table_4
    union all
select * from table_5
    union all
select * from table_6
    union all
select * from table_7
    union all
select * from table_8
    union all
select * from table_9
    union all
select * from table_10
    union all
select * from table_11
    union all
select * from table_12
;
sales_division_123m
sales_division_124m
sales_division_125m
....
create or replace function combine_tables (table_pattern varchar(100))
returns table ("" varchar(10000)) as --empty header for easy copying and pasting

$$  
(
select 'create or replace view named_whatever as'
union all
select  concat('select * from ' , 
                lower(table_name), 
                case when table_name < max(table_name) over() then ' union all' 
                     else ';' end)
from warehouse_name.information_schema.tables
where table_name ilike table_pattern
order by 1
)
$$;
select *
from table(combine_tables('sales_division_%m'));
create view named_whatever as

select * from sales_division_123m union all
select * from sales_division_124m union all
select * from sales_division_125m;