简体   繁体   English

根据另一个表的数据在 FOR 循环中执行 Snowflake SQL 查询

[英]Perform Snowflake SQL queries in FOR LOOP based on data from another table

In Snowflake, I am trying to create a SQL script with a for loop that outputs the results into a new table based on the the data_type column在 Snowflake 中,我正在尝试创建一个带有 for 循环的 SQL 脚本,该脚本将结果输出到基于 data_type 列的新表中

I have a table called PROFILE_TABLE_LIST that has the columns with a table name and column name, and data type as shown below:我有一个名为 PROFILE_TABLE_LIST 的表,其中包含表名和列名以及数据类型的列,如下所示:

TABLENAME表名 COLUMN_NAME COLUMN_NAME DATA_TYPE数据类型
Table1表格1 PLANTS植物 TEXT文本
Table1表格1 HEIGHT高度 FLOAT漂浮
Table2表2 COLOR颜色 TEXT文本
Table2表2 SMELL TEXT文本

I am currently trying to do a for loop using a cursor and perform the queries on each of the rows to profile the table based on the column types to look something like this:我目前正在尝试使用 cursor 执行 for 循环,并对每一行执行查询以根据列类型分析表,如下所示:

TABLENAME表名 COLUMN_NAME COLUMN_NAME DATA_TYPE数据类型 COUNT数数 MAX_LENGTH最长长度 MAX_VALUE MAX_VALUE
Table1表格1 PLANTS植物 TEXT文本 10 10 82 82 NULL NULL
Table1表格1 HEIGHT高度 FLOAT漂浮 10 10 NULL NULL 58.6 58.6
Table2表2 COLOR颜色 TEXT文本 20 20 56 56 NULL NULL
Table2表2 SMELL TEXT文本 20 20 23 23 NULL NULL

Eventually, I want to run different select statements conditioned on the data_type, but at this stage, I am only focusing on the count.最终,我想根据 data_type 运行不同的 select 语句,但在这个阶段,我只关注计数。 This is the current loop I have.这是我的当前循环。 However, the select statement is not getting executed properly as the table name is being passed as a string, and if I use TABLE(tablename) I receive a syntax error (I have that line commented out below:但是,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;

I would build a block of SQL and run it at the end.我会构建一个 SQL 的块并在最后运行它。

Which initialing using a simple SELECT as a pattern to show the building up process, that you could write your own dynamic sql from:使用简单的 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;

which gives:这使:

THE_BIG_SQL 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' as COLUMN_NAME, 'FLOAT' as DATA_TYPE, count(HEIGHT) as count, null as max_length, MAX(HEIGHT) as max_value FROM Table1 UNION ALL SELECT 'Table2' as TABLENAME, 'COLOR' as COLUMN_NAME, 'TEXT' as 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 count, MAX(LEN(SMELL)) as max_length, null as max_value FROM Table2 SELECT 'Table1' 作为 TABLENAME,'PLANTS' 作为 COLUMN_NAME,'TEXT' 作为 DATA_TYPE,count(PLANTS) 作为计数,MAX(LEN(PLANTS)) 作为 max_length,null 作为 max_value FROM Table1 UNION ALL SELECT 'Table1' 作为 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) 作为计数,MAX(LEN(COLOR)) 作为 max_length,null 作为 max_value FROM Table2 UNION ALL SELECT 'Table2' 作为 TABLENAME,'SMELL' 作为 COLUMN_NAME,'TEXT' 作为 DATA_TYPE,count(SMELL) 作为计数,MAX(LEN(SMELL)) 作为 max_length,null 作为 Table2 的 max_value

Which if ran against these tables:如果针对这些表运行:

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');

gives:给出:

TABLENAME表名 COLUMN_NAME COLUMN_NAME DATA_TYPE数据类型 COUNT数数 MAX_LENGTH最长长度 MAX_VALUE MAX_VALUE
Table1表格1 PLANTS植物 TEXT文本 3 3个 12 12
Table1表格1 HEIGHT高度 FLOAT漂浮 3 3个 10.1 10.1
Table2表2 COLOR颜色 TEXT文本 2 2个 4 4个
Table2表2 SMELL TEXT文本 2 2个 4 4个

But here is the dynamic answer fully written for you:但这是为您完全编写的动态答案:

first making the TABLE with the work to be done:首先用要完成的工作制作 TABLE:

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);

and using the prior created "real data.tables" we can use:并使用之前创建的“real data.tables”我们可以使用:

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;

gives:给出:

TABLENAME表名 COLUMN_NAME COLUMN_NAME DATA_TYPE数据类型 COUNT数数 MAX_LENGTH最长长度 MAX_VALUE MAX_VALUE
Table1表格1 PLANTS植物 TEXT文本 3 3个 12 12
Table1表格1 HEIGHT高度 data_type数据类型 3 3个 10.1 10.1
Table2表2 COLOR颜色 TEXT文本 2 2个 4 4个
Table2表2 SMELL TEXT文本 2 2个 4 4个

is it possible to replace the table in this part, after the FROM?是否可以在 FROM 之后替换这部分中的表格? I want to replace it with the actual name of the table我想用表的实际名称替换它

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||' sql:= '''||record.tablename||''' 作为 TABLENAME,'''||record.column_name||''' 作为 COLUMN_NAME,'''||record.data_type||'''作为 DATA_TYPE,count('||record.column_name||') 作为计数,MAX(LEN('||record.column_name||')) 作为 max_length,null 作为 max_value FROM '||record.tablename||' '; ';

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 基于匹配值的另一个表的雪花 SQL Sum - Snowflake SQL Sum from another table based on matching values Snowflake SQL 根据匹配值从另一个表计数和求和 - Snowflake SQL Counting and Summing from Another Table based on Matching Value 如何执行sql操作以根据与另一个表匹配的主键将数据插入第二个表? - How to perform sql operation to insert data into a second table based on primary key matching to another table? SQL-使用其他表中的条件执行SELECT - SQL - Perform SELECT with condition from another table SQL-如何对来自同一表的多个查询执行嵌套SELECT? - SQL - How to perform a nested SELECT with multiple queries from the same table? 根据雪花中多个表的数据更新单个表 - Update a single table based on data from multiple tables in snowflake MS Access 2013-如何根据另一个表中的MAX日期以ID执行SQL更新? - MS Access 2013 - How to perform a SQL Update with id based on MAX date from another table? 在雪花/SQL 中从 JSON 数据子 arrays 创建表 - Creating a table from JSON data sub arrays within in snowflake/SQL SQL大量插入基于从另一个表提取的数据 - SQL mass insert based off of data pulled from another table 根据另一个SQL PHP的结果从一个表获取数据 - Getting data from one table based on results of another SQL PHP
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM