微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在BigQuery中,确定何时UNION ALL上的列不匹配

如何解决在BigQuery中,确定何时UNION ALL上的列不匹配

with
  table1 as (
    select 'joe' as name,17 as age,25 as speed
  ),table2 as (
    select 'nick' as name,21 as speed,23 as strength
  )

select * from table1
union all
select * from table2

在Google BigQuery中,此union all不会引发错误,因为两个表的列数相同(每列3个)。但是,由于列不匹配,我收到了不好的数据输出。与输出带有正确值+空值(缺少值)(可能会更好)的四列nameagespeedstrength的新表不同,{ {1}}将3列保留在第一行。

是否有一种很好的方法来捕获列不匹配,而不是查询以静方式返回不良数据?相对于成功的表,有没有办法返回错误?我不确定如何在sql中检查2个表中的列是否匹配。

编辑:在此示例中,很明显看到列不匹配,但是在我们的数据中,我们有100多个列,并且我们希望避免出现以下情况:联盟全部

解决方法

以下内容适用于BigQuery标准SQL,并使用BQ的脚本功能

DECLARE statement STRING;
SET statement = (
  WITH  table1_columns AS (
    SELECT column FROM (SELECT * FROM `project.dataset.table1` LIMIT 1) t,UNNEST(REGEXP_EXTRACT_ALL(TRIM(TO_JSON_STRING(t),'{}'),r'"([^"]*)":')) column
  ),table2_columns AS (
    SELECT column FROM (SELECT * FROM `project.dataset.table2` LIMIT 1) t,all_columns AS (
    SELECT column FROM table1_columns UNION DISTINCT SELECT column FROM table2_columns
  )
  SELECT (
      SELECT 'SELECT ' || STRING_AGG(IF(t.column IS NULL,'NULL as ','') || a.column,',') || ' FROM `project.dataset.table1` UNION ALL '
      FROM all_columns a LEFT JOIN table1_columns t USING(column)
    ) || (
      SELECT 'SELECT ' || STRING_AGG(IF(t.column IS NULL,') || ' FROM `project.dataset.table2`'
      FROM all_columns a LEFT JOIN table2_columns t USING(column)
    ) 
);
EXECUTE IMMEDIATE statement;   

应用于问题中的样本数据时-输出为

Row name    age     speed   strength     
1   joe     17      25      null     
2   nick    null    21      23   
,

table1table2保存为BigQuery数据集中的2个表之后,然后使用INFORMATION_SCHEMA使用元数据来检查列是否匹配。

SELECT *
FROM models.INFORMATION_SCHEMA.COLUMNS
where table_name = 'table1'

SELECT *
FROM models.INFORMATION_SCHEMA.COLUMNS
where table_name = 'table2'

INFORMATION_SCHEMA.COLUMNS返回的信息包括列名及其。我可以将这两个表连接在一起,然后检查名称是否匹配...

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。