3

我想使用 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_ALL' 的 GROUP_CONCAT 作为分隔符,但我无法取得进展。

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

4

3 回答 3

1

在雪花中,这个动态 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.

$$...$$ 是字符串文字单引号的替代方案。您还可以通过将单引号加倍来转义单引号。

于 2019-11-28T14:25:25.523 回答
0

也许是这样的:

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%';
于 2019-11-01T17:03:52.163 回答
0

如果我理解正确:

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
于 2019-07-08T16:28:14.667 回答