Snowflake 我们如何遍历 temp table 的每一行并将其值插入到另一个 table 中,其中每个字段及其值都是一行?

Snowflake how can we loop over each row of a temp table and insert its values with into another table where each field with its value is a single row?

我们正在将数据加载到事实 table,我们在 Snowflake 上的原始临时文件 table 如下所示:

其中 indicator_nbr 字段是调查中提出的问题。

我们正在使用数据建模技术来构建我们的仓库数据库,因此数据将被添加到事实中 table,如下所示:

那么指标2、3同理,还有其他问题依此类推

每个字段及其值都将作为一行。当然还有其他元数据要添加,如 load_dtrecord_src 但它们不是问题。

当前脚本正在执行以下操作:

  1. 将字段放入数组=> fields_array = ['indicator_1', 'indicator_2', 'indicator_3']

  2. 一个循环将 运行 遍历数组并开始为每一行添加每个字段及其值。所以假设我们有 100 行,我们将 运行 300 个插入,一次一个:

    for (var col_num = 0; col_num<fields_array.length; col_num = col_num+1) {

        var COL_NAME = fields_array[col_num];
    
        var field_value_query = "INSERT INTO SAT_FIELD_VALUE SELECT md5(id), CURRENT_TIMESTAMP(), NULL, 'SRC', "+COL_NAME+", md5(foreign_key_field) FROM "+TEMP_TABLE_NAME+"";
    

    }

正如在显示完整脚本的 this post 的评论中提到的,最好循环一个字符串来连接插入查询的每个 from values

建议的解决方案有 2 个问题:

  1. Snowflake 上的查询有大小限制(应小于 1 MB);
  2. 如果我们要遍历每个字段并连接 from values,我们还应该从临时 table 执行 select 查询以获取列的值,所以不会有优化,或者我们会减少一点点但不会太多。

编辑:一个可能的解决方案

我正在考虑做一个 sql 查询,从临时 table 中选择所有内容,然后进行散列和所有内容,并在转置后将其保存到数组中,但我不知道该怎么做它。

不确定这是否是您要查找的内容,但您似乎只想做一个枢轴:

设置示例场景

create or replace transient table source_table
(
    id          number,
    indicator_1 varchar,
    indicator_2 number,
    indicator_3 varchar
);

insert overwrite into source_table
values (1, 'Test', 2, 'DATA'),
       (2, 'Prod', 3, 'DATA'),
       (3, 'Test', 1, 'METADATA'),
       (4, 'Test', 1, 'DATA')
;

create or replace transient table target_table
(
    hash_key varchar,
    md5      varchar
);

运行插入

select
    name_col as hash_key,
    md5(id)
from (select
          id,
          indicator_1,
          indicator_2::varchar as indicator_2,
          indicator_3
      from source_table) unpivot ( val_col for name_col in (indicator_1, indicator_2, indicator_3))
;

这导致 target_table 看起来像这样:

+-----------+--------------------------------+
|HASH_KEY   |MD5                             |
+-----------+--------------------------------+
|INDICATOR_1|c4ca4238a0b923820dcc509a6f75849b|
|INDICATOR_2|c4ca4238a0b923820dcc509a6f75849b|
|INDICATOR_3|c4ca4238a0b923820dcc509a6f75849b|
|INDICATOR_1|c81e728d9d4c2f636f067f89cc14862c|
|INDICATOR_2|c81e728d9d4c2f636f067f89cc14862c|
|INDICATOR_3|c81e728d9d4c2f636f067f89cc14862c|
|INDICATOR_1|eccbc87e4b5ce2fe28308fd9f2a7baf3|
|INDICATOR_2|eccbc87e4b5ce2fe28308fd9f2a7baf3|
|INDICATOR_3|eccbc87e4b5ce2fe28308fd9f2a7baf3|
|INDICATOR_1|a87ff679a2f3e71d9181a67b7542122c|
|INDICATOR_2|a87ff679a2f3e71d9181a67b7542122c|
|INDICATOR_3|a87ff679a2f3e71d9181a67b7542122c|
+-----------+--------------------------------+

使用场景很棒 INSERT ALL:

INSERT ALL
INTO dst_tab(hash_key, md5) VALUES (indicator_1, md5)
INTO dst_tab(hash_key, md5) VALUES (indicator_2, md5)
INTO dst_tab(hash_key, md5) VALUES (indicator_3, md5) 
SELECT MD5(id) AS md5, indicator_1, indicator_2::STRING AS indicator_2, indicator_3 
FROM src_tab;