【问题标题】:What is the best way to UNION ALL BigQuery tables with different data types and different columns?合并具有不同数据类型和不同列的所有 BigQuery 表的最佳方法是什么?
【发布时间】:2020-01-15 22:12:34
【问题描述】:

我在一个 BigQuery 项目下有大约 50 个表,这些表由不同平台的 ETL 工具创建。表中没有主键,很少有表的列超过 100。 每个平台都有不同的字段和不同的数据类型,团队的要求是创建一个所有表合并的一个大主表

我通过在 Excel 中列出表的所有列并将表中不存在的字段清空以形成对每个表的查询和 UNION ALL 一起创建主表来手动完成此任务。 然后我在 BigQuery 中安排它每天刷新。

例如:

Tbl A   Tbl B   Tbl C
char1   char1   char1
num1    num3    num1
char2   char2   char2
    char5   num2
    num2    num3
        char3
        char4

手动查询:

With mast_tbl as (
select concat(cast(row_number() over (partition by date) as string), ' | ', ' TblA) as pk_client , 
char1,
num1,
char2,
null as num3,
cast(null as string) as char5,
null as num2,
cast(null as string) as char3,
cast(null as string) as char4

FROM `bigquery-project-XXXX.export_TblA.all _data_view`

UNION ALL

select concat(cast(row_number() over (partition by date) as string),' | ', ' TblB) as pk_client , 
char1,
null as num1,
char2,
num3,
char5,
num2,
cast(null as string) as char3,
cast(null as string) as char4

FROM `bigquery-project-XXXX.export_TblB.all _data_view`

select concat(cast(row_number() over (partition by date) as string), ' | ', ' TblC) as pk_client , 
char1,
num1,
char2,
num3,
cast(null as string) as char5,
num2,
char3,
char4

FROM `bigquery-project-XXXX.export_TblC.all _data_view`

)
Select * from mast_tbl

这可行,但是手动工作量很大,特别是如果我们要添加新表或新列或删除列,这将使我在每个表查询时都进行更改以使 UNION ALL 正常工作。 所以,我想知道是否有任何方法可以自动化脚本或我们应该执行此任务的任何其他方式。

【问题讨论】:

  • “团队的要求是把所有的表合并成一个大的主表”我要问为什么?

标签: sql google-bigquery union union-all


【解决方案1】:

您可以从INFORMATION_SCHEMA 表中生成查询。查询本身会更加混乱,但您可以轻松地重新生成它。

这还要求所有表都在同一个数据集中,因此首先要为每个表创建一个视图。

查询生成思路是:

with tables as (
      select 'vw_export_TblA' as table_name union all
      select 'vw_export_TblB' as table_name union all
      . . .
     ),
     columns as (
      select 'char1' as column_name, 'string' as type union all
      select 'num1' as column_name, 'int64' as type union all
      . . .
     ) 
select string_agg(table_query, ' union all ')  
from (select concat('select ',
                    string_agg(coalesce(ic.column_name, concat('cast(null as ', c.type, ')')), ', ')
                    ' from ',
                    table_name
                   ) as table_query
      from tables t cross join
           columns c left join
           `?.INFORMATION_SCHEMA.COLUMNS` ic
     on ic.table_name = t.table_name and
              ic.column_name = c.column_name
     group by t.table_name
    ) c;

这个想法并不是说结果很漂亮。这个想法是您可以从结果中创建一个表或视图。并且您可以通过扩展 CTE 中的列表来控制表和列。

您需要一些时间才能让此查询适合您的环境——比任何一次手动迭代都要长。但是,下次您必须更改类型或列时,它会容易得多。

注意:您也可以将其放在 Python 等语言中。简单地允许字符串中的换行符会使结果更漂亮。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-20
    • 2022-09-27
    • 2011-03-18
    • 2016-05-14
    • 1970-01-01
    • 2016-08-23
    • 2016-10-14
    • 1970-01-01
    相关资源
    最近更新 更多