基于另一个表中的数据在 FOR LOOP 中执行 Snowflake SQL 查询

不笑

在雪花中,我正在尝试创建一个带有 for 循环的 SQL 脚本,该循环将结果输出到基于 data_type 列的新表中

我有一个名为 PROFILE_TABLE_LIST 的表,其中的列具有表名和列名,数据类型如下所示:

表名 COLUMN_NAME 数据类型
表格1 植物 文本
表格1 高度 漂浮
表2 颜色 文本
表2 文本

我目前正在尝试使用游标执行 for 循环,并对每一行执行查询,以根据列类型对表进行分析,使其看起来像这样:

表名 COLUMN_NAME 数据类型 数数 最长长度 MAX_VALUE
表格1 植物 文本 10 82 空值
表格1 高度 漂浮 10 空值 58.6
表2 颜色 文本 20 56 空值
表2 文本 20 23 空值

最终,我想根据 data_type 运行不同的 select 语句,但在这个阶段,我只关注计数。这是我拥有的当前循环。但是,选择语句没有得到正确执行,因为表名作为字符串传递,如果我使用 TABLE(tablename) 我收到语法错误(我在下面注释掉了该行:

declare
    tablename string;
    column_name string;
    row_count integer;
    table_schema string;
    table_catalog string;
    name string;
    
    tmp_array ARRAY default ARRAY_CONSTRUCT();

    res resultset default (select * from PROFILE_TABLE_LIST);
    c1 cursor for res;
    rs_output RESULTSET;
begin

  for record in c1 do
    tablename := record.TABLENAME;
    column_name := record.column_name;
    table_schema := record.table_schema;
    table_catalog := record.table_catalog;
   
   
    
    tmp_array := array_append(:tmp_array, OBJECT_CONSTRUCT('tmp_tables', record.TABLENAME, 'COUNT', (SELECT COUNT(column_name) FROM tablename)));
    -- tmp_array := array_append(:tmp_array, OBJECT_CONSTRUCT('tmp_tables', record.TABLENAME, 'COUNT', (SELECT COUNT(column_name) FROM TABLE(tablename))));
 
     
    
  end for;

  rs_output := (select value:tmp_tables, value:COUNT from table(flatten(:tmp_array)));
  return table(rs_output);
end;
西缅朝圣者

我会构建一个 SQL 块并在最后运行它。

使用简单的 SELECT 作为模式来显示构建过程的初始化,您可以从以下位置编写自己的动态 sql:

WITH table_list as (
    SELECT * FROM VALUES
    ('Table1', 'PLANTS', 'TEXT'),
    ('Table1', 'HEIGHT', 'FLOAT'),
    ('Table2', 'COLOR', 'TEXT'),
    ('Table2', 'SMELL', 'TEXT')
    v(tablename, column_name, data_type)
), to_rows as (
    SELECT
        tablename
        ,CASE data_type
            WHEN 'TEXT' THEN 'SELECT ''tablename'' as TABLENAME, ''column_name'' as COLUMN_NAME, ''data_type'' as DATA_TYPE, count(column_name) as count, MAX(LEN(column_name)) as max_length, null as max_value FROM tablename '
            WHEN 'FLOAT' THEN 'SELECT ''tablename'' as TABLENAME, ''column_name'' as COLUMN_NAME, ''data_type'' as DATA_TYPE, count(column_name) as count, null as max_length, MAX(column_name) as max_value FROM tablename '
        END as sql
        ,REPLACE(REPLACE(REPLACE(sql, 'data_type', data_type), 'column_name', column_name), 'tablename', tablename) as final_sql
    FROM table_list
)
SELECT
    listagg (final_sql, ' UNION ALL ') within group(order by tablename) as the_big_sql
FROM to_rows;

这使:

THE_BIG_SQL
SELECT 'Table1' as TABLENAME, 'PLANTS' as COLUMN_NAME, 'TEXT' as DATA_TYPE, count(PLANTS) as count, MAX(LEN(PLANTS)) as max_length, null as max_value FROM Table1 UNION ALL SELECT 'Table1' as TABLENAME, 'HEIGHT' 作为 COLUMN_NAME,'FLOAT' 作为 DATA_TYPE,count(HEIGHT) 作为计数,null 作为 max_length,MAX(HEIGHT) 作为 max_value FROM Table1 UNION ALL SELECT 'Table2' 作为 TABLENAME,'COLOR' 作为 COLUMN_NAME,'TEXT' 作为DATA_TYPE, count(COLOR) as count, MAX(LEN(COLOR)) as max_length, null as max_value FROM Table2 UNION ALL SELECT 'Table2' as TABLENAME, 'SMELL' as COLUMN_NAME, 'TEXT' as DATA_TYPE, count(SMELL) as计数,MAX(LEN(SMELL)) 作为 max_length,null 作为 max_value FROM Table2

如果针对这些表运行:

create table table1(plants text, height float);
create table table2(color text, smell text);

insert into table1 values ('big plant', 10.1),('medium plant', 5.3),('tiny', 1.0);
insert into table2 values ('red', 'bold'), ('blue', 'weak');

给出:

表名 COLUMN_NAME 数据类型 数数 最长长度 MAX_VALUE
表格1 植物 文本 3 12
表格1 高度 漂浮 3 10.1
表2 颜色 文本 2 4
表2 文本 2 4

但这是为您完全编写的动态答案:

首先制作要完成的工作的表格:

CREATE TABLE PROFILE_TABLE_LIST AS 
SELECT * FROM VALUES
    ('Table1', 'PLANTS', 'TEXT'),
    ('Table1', 'HEIGHT', 'FLOAT'),
    ('Table2', 'COLOR', 'TEXT'),
    ('Table2', 'SMELL', 'TEXT')
    v(tablename, column_name, data_type);

并使用之前创建的“真实数据表”,我们可以使用:

declare
    sql string;
    final_sql string;
    c1 cursor for (select * from PROFILE_TABLE_LIST);
    res resultset;
begin
  final_sql := '';
  
  for record in c1 do
    if(record.data_type = 'TEXT') THEN
        sql := 'SELECT '''||record.tablename||''' as TABLENAME, '''||record.column_name||''' as COLUMN_NAME, '''||record.data_type||''' as DATA_TYPE, count('||record.column_name||') as count, MAX(LEN('||record.column_name||')) as max_length, null as max_value FROM '||record.tablename||' ';
    else
        sql := 'SELECT '''||record.tablename||''' as TABLENAME, '''||record.column_name||''' as COLUMN_NAME, ''data_type'' as DATA_TYPE, count('||record.column_name||') as count, null as max_length, MAX('||record.column_name||') as max_value FROM '||record.tablename||' ';
    end if;
    if(final_sql<>'')then 
        final_sql := final_sql || ' UNION ALL ';
    end if;
    final_sql := final_sql || sql;
        
  end for;

  res := (execute immediate :final_sql);
  return table(res);
end;

给出:

表名 COLUMN_NAME 数据类型 数数 最长长度 MAX_VALUE
表格1 植物 文本 3 12
表格1 高度 数据类型 3 10.1
表2 颜色 文本 2 4
表2 文本 2 4

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

SQL从查询结果中替换另一个表中的多个变量

在另一个SQL查询中执行一个SQL查询

如何在1个SQL查询中计算另一个表中的行数

使用另一个表中的条件查询SQL表

具有多个表的SQL查询以从一个表中获取数据并在另一个表中进行填充

基于SQL Server中另一个查询的Where子句

SQL查询考虑当前表中的行,并排除另一个表中存在的数据

SQL查询:将列中的数据用作另一个表中的列名?

如何使用SQL SELECT基于另一个表中的特定行查询表

SQL:如何从另一个表中按值查询表?

在我的SQL查询中,如何有一个包含从另一个表查询的值的列?

SQL查询以基于另一个表中的列值从一个表中选择

R中的数据砖中的SQL Snowflake查询

计算同一查询中另一个SQL表中的行

SQL查询另一个表中的值

SQL-从另一个表中获取一列以加入此查询

SQL Server:查询以将数据从具有不同结构的另一个表插入表中

Oracle SQL查询表并根据结果从另一个表中删除

MS Access SQL:基于另一个表中的总和从一个表中返回数据

SQL查询-从一个表中选择全部,在另一个表中匹配记录

使用另一个表中的条件从表中进行SQL查询

Codeigniter SQL 查询:我想使用另一个表中的数据从一个表中检索数据

SQL Server:查询以从另一个表中获取表数据(计数)作为 VIEW

Sql查询 - 我在一个表中有三列,我需要将每列数据检查到另一个表中

在 Snowflake 中查询变体数据

SQL Server:查询以从同一个表和另一个表中获取数据

基于另一个表的 SQL 查询

关于如何从另一个表中获取随机记录到另一个表上的每一行的查询的 SQL 查询?

SQL 对于表中的每个值,根据该值对另一个表执行查询