Snowflake Dynamic SQL to select subset of columns in one table from undetermined number of values in another table

107 Views Asked by At

I need to create a SQL script that will run daily and select a subset of columns from table A. The subset of columns is defined in table B - it will be periodically edited by marketing team and can have any subset of the columns in table A

example:

Table_A has 100 columns: [Column1], [Column2], ..., [Column100]

Table_B has 1 column: [ColumnNames] with the values 'Column1', 'Column3', 'Column8'

How do I write a dynamic query

SELECT **Column1, Column3, Column8**
FROM Table_A

where the list of columns (in bold) comes from the query

SELECT LISTAGG(DISTINCT ColumnNames, ', ')
FROM Table_B 

I tried the following:

SET ColumnList = (SELECT LISTAGG(DISTINCT ColumnNames, ', ') FROM Table_B );
SET SQLScript = (SELECT CONCAT('SELECT ', $ColumnList, ' FROM Table_A'));
EXECUTE IMMEDIATE $SQLScript;

This works well as long as the character size of the variable SQLScript does not exceed 256, but I cannot count on that being true since marketing may select to include many ColumnNames in Table_B

1

There are 1 best solutions below

4
Felipe Hoffa On BEST ANSWER

Using the style as suggested by @Mat on their comment, with 500 columns:

EXECUTE IMMEDIATE $$
    BEGIN   
        let concat_cols string := (
            select listagg(x, ', ') 
            from (select a.$1 x from values('a'),('b'),('c') a 
            join (select 1 from TABLE(GENERATOR(ROWCOUNT => 500))))
            );
        let long_select string := 'select ' || concat_cols || ' from (select 1 a, 2 b, 3 c)';
        let res resultset := (EXECUTE IMMEDIATE long_select);
        return table(res);
    END;
$$
;

These variables don't have the 256 character limit.

https://docs.snowflake.com/en/developer-guide/snowflake-scripting/variables

enter image description here