Sql 循环并将模式/表与UNION_ALL组合

Sql 循环并将模式/表与UNION_ALL组合,sql,dynamic-sql,group-concat,snowflake-cloud-data-platform,Sql,Dynamic Sql,Group Concat,Snowflake Cloud Data Platform,我想使用UNION_ALL组合来自不同模式的表。这些表具有相同的架构,如本示例中所示: class1.names +----------+ | id | name| +----------+ | 1 | jon | | 2 | ann | | 3 | rob | class2.names +----------+ | id | name| +----------+ | 1 | rav | | 2 | meg | | 3 | mat | 我可以将类列表硬编码到数组中,或者更优选地,

我想使用UNION_ALL组合来自不同模式的表。这些表具有相同的架构,如本示例中所示:

class1.names
+----------+
| id | name|
+----------+
| 1  | jon |
| 2  | ann |
| 3  | rob |

class2.names
+----------+
| id | name|
+----------+
| 1  | rav |
| 2  | meg |
| 3  | mat |
我可以将类列表硬编码到数组中,或者更优选地,使用如下查询获取它们:

SELECT DISTINCT(TABLE_SCHEMA)
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_TYPE = 'BASE TABLE'
我想这样组合这些表:

SELECT *, 'class1' as class FROM class1.names
UNION_ALL
SELECT *, 'class2' as class FROM class2.names
UNION_ALL
etc.
但是在模式级查询中会有比
SELECT*,'class1'…
更多的内容,所以我想使用循环或其他系统方法来实现这一点

我正在研究动态sql或使用带有“UNION\u ALL”的GROUP\u CONCAT作为分隔符,但我在取得进展方面遇到了困难


附录:我知道这是一个糟糕的模式设计,但我现在对此无能为力。

如果我正确理解您的观点:

select listagg('select ' || f.value, ' union all ') from table(flatten(input => parse_json(
                                                    '[1, ,77]'))) f;
+----------------------------------------------+
| LISTAGG('SELECT ' || F.VALUE, ' UNION ALL ') |
|----------------------------------------------|
| select 1 union all select 77                 |
+----------------------------------------------+
1 Row(s) produced. Time Elapsed: 0.739s
除此之外:

select 1 union all select 77;
+----+
|  1 |
|----|
|  1 |
| 77 |
+----+
2 Row(s) produced. Time Elapsed: 0.638s
可能是这样的:

SELECT DISTINCT case when row_number() OVER (ORDER BY lower(table_schema) || '.' || lower(table_name)) > 1 then 'UNION ALL ' else '' end ||
                   'SELECT *, ''' || lower(table_schema) || ''' AS class FROM ' || lower(table_schema) || '.' || lower(table_name) || '' union_stmt
FROM INFORMATION_SCHEMA.TABLES 
WHERE table_type = 'BASE TABLE'
and table_name like 'HPSA%';

在Snowflake中,此动态SQL:

with a as (
  select * from information_schema.tables 
  where table_catalog like 'CLASS%' and table_name = 'NAMES' and table_type = 'BASE TABLE'
),

b as (
  select *, 
    $$SELECT *, 'SCHEMA' as class FROM SCHEMA.names$$ as t,
    replace(t,'SCHEMA',lower(table_schema)) as sql,
  from a
)

select listagg(sql,'\nUNION ALL\n') within group (order by table_schema, table_catalog)
from b;
将产生:

SELECT *, 'class1' as class FROM class1.names
UNION ALL
SELECT *, 'class2' as class FROM class2.names
UNION ALL
etc.
$$…$$是字符串文字单引号的替代方法。您还可以通过将单引号加倍来避开单引号