在 BigQuery 中,确定列何时与 UNION ALL 不匹配
In BigQuery, identify when columns do not match on 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
不会引发错误,因为两个 table 具有相同的列数(每个 3)。但是我收到错误的数据输出,因为列不匹配。而不是输出具有 4 列 name
、age
、speed
、strength
的新 table 以及正确的值 + 缺失值的空值(这可能是首选),union all
保留顶行的 3 列。
有没有一种好方法可以发现列不匹配,而不是静默查询 returning 错误数据?有什么方法可以 return 一个错误,而不是一个成功的 table?我不确定如何在 SQL 中检查 2 table 中的列是否匹配。
编辑: 在此示例中,可以清楚地看到列不匹配,但是在我们的数据中,我们有 100 多列,我们希望避免出现以下情况在 UNION ALL
中出错
将 table1
和 table2
保存为 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
returns 信息包括列名称 和 它们的位置。我可以将这两个表连接在一起,然后检查名称是否匹配...
以下适用于 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,
UNNEST(REGEXP_EXTRACT_ALL(TRIM(TO_JSON_STRING(t), '{}'), r'"([^"]*)":')) column
), 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, 'NULL as ', '') || a.column, ', ') || ' 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
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
不会引发错误,因为两个 table 具有相同的列数(每个 3)。但是我收到错误的数据输出,因为列不匹配。而不是输出具有 4 列 name
、age
、speed
、strength
的新 table 以及正确的值 + 缺失值的空值(这可能是首选),union all
保留顶行的 3 列。
有没有一种好方法可以发现列不匹配,而不是静默查询 returning 错误数据?有什么方法可以 return 一个错误,而不是一个成功的 table?我不确定如何在 SQL 中检查 2 table 中的列是否匹配。
编辑: 在此示例中,可以清楚地看到列不匹配,但是在我们的数据中,我们有 100 多列,我们希望避免出现以下情况在 UNION ALL
中出错将 table1
和 table2
保存为 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
returns 信息包括列名称 和 它们的位置。我可以将这两个表连接在一起,然后检查名称是否匹配...
以下适用于 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,
UNNEST(REGEXP_EXTRACT_ALL(TRIM(TO_JSON_STRING(t), '{}'), r'"([^"]*)":')) column
), 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, 'NULL as ', '') || a.column, ', ') || ' 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